转换运算符+转换构造函数=非直观行为? [英] Conversion operator + conversion constructor = unintuitive behavior?

查看:112
本文介绍了转换运算符+转换构造函数=非直观行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白为什么下面的代码打印 struct Value 而不是 int (这意味着转换构造函数正在转换为 Value ,而不是 int )。 (Visual C ++ 2012)

I don't understand why the code below prints struct Value instead of int (which implies the conversion constructor is converting to Value instead of int). (Visual C++ 2012)

为什么会发生这种情况?为什么编译器完全忽略 Value(int)构造函数?

Why is this happening? Why does the compiler completely ignore the Value(int) constructor?

#include <iostream>
#include <type_info>

using namespace std;

struct Value { Value(int) { } };

struct Convertible
{
    template<class T>
    operator T() const
    { throw typeid(T).name(); }
};

int main()
{
    try { Value w((Convertible())); }
    catch (char const *s) { cerr << s << endl; }
}



编辑:



更奇怪的是(这次只有C ++ 11,在GCC 4.7.2):

Even more bizarre is this (this time it's C++11 only, on GCC 4.7.2):

#include <iostream>
#include <typeinfo>

using namespace std;

struct Value
{
    Value(Value const &) = delete;
    Value(int) { }
};

struct Convertible
{
    template<class T>
    operator T() const
    { throw typeid(T).name(); }
};

int main()
{
    try { Value w((Convertible())); }
    catch (char const *s) { cerr << s << endl; }
}

其中:

source.cpp: In function 'int main()':
source.cpp:21:32: error: call of overloaded 'Value(Convertible)' is ambiguous
source.cpp:21:32: note: candidates are:
source.cpp:9:3: note: Value::Value(int)
source.cpp:8:3: note: Value::Value(const Value&) <deleted>

如果复制构造函数被删除,那么为什么会出现歧义?!

If the copy constructor is deleted, then why is there any ambiguity?!

推荐答案

在第一个示例中,Visual Studio不正确;该调用是不明确的。 gcc在C ++ 03模式中打印:

In the first example Visual Studio is incorrect; the call is ambiguous. gcc in C++03 mode prints:

source.cpp:21:34: error: call of overloaded 'Value(Convertible)' is ambiguous
source.cpp:21:34: note: candidates are:
source.cpp:9:5: note: Value::Value(int)
source.cpp:6:8: note: Value::Value(const Value&)

隐式默认。管理段是 13.3.1.3通过构造函数[over.match.ctor]初始化


类类型是直接初始化[...],重载分辨率选择构造函数。对于直接初始化,候选函数是被初始化的对象的类的所有构造函数。

When objects of class type are direct-initialized [...], overload resolution selects the constructor. For direct-initialization, the candidate functions are all the constructors of the class of the object being initialized.

功能同等地参与过载分辨率;它们只在一旦重载已经解决时影响编译,当选择被删除的功能的程序是不成形的。标准中的激励示例是只能由浮点类型构造的类:

In the second example, deleted functions participate equally in overload resolution; they only affect compilation once overloads have been resolved, when a program that selects a deleted function is ill-formed. The motivating example in the standard is of a class that can only be constructed from floating-point types:

struct onlydouble {
  onlydouble(std::intmax_t) = delete;
  onlydouble(double);
};

这篇关于转换运算符+转换构造函数=非直观行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆