我不明白为什么下面的代码会打印struct Value
代替int
(这意味着转换构造函数正在转换为Value
代替int
)。 (视觉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; }
}
Edit:
更奇怪的是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 不正确;该调用含糊不清。 C++03 模式下的 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]:
当直接初始化类类型的对象时[...],重载决策会选择构造函数。对于直接初始化,候选函数是被初始化对象的类的所有构造函数。
在第二个示例中,删除的函数同样参与重载决策;它们仅在解决重载后(当选择已删除函数的程序格式错误时)才会影响编译。标准中的激励示例是只能从浮点类型构造的类:
struct onlydouble {
onlydouble(std::intmax_t) = delete;
onlydouble(double);
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)