我不明白为什么下面的代码打印结构值而不是int(这意味着转换构造函数正在转换为值而不是int). (Visual C 2012)
为什么会发生这种情况?为什么编译器完全忽略Value(int)构造函数?
#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; } }
编辑:
更奇怪的是this(这次是C 11,在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>
解决方法
在第一个示例中,Visual Studio不正确;电话是不明确的. C03模式下的gcc打印:
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.
在第二个例子中,已删除的函数同样参与过载解析;当一个程序选择已删除的功能时,它们只影响一旦重载已经解决了,编译就会形成.标准中的激励例子是一个只能用浮点类型构建的类:
struct onlydouble { onlydouble(std::intmax_t) = delete; onlydouble(double); };