转换运算符+转换构造函数=不直观的行为?

时间:2012-12-19 10:43:21

标签: c++ visual-c++ implicit-conversion

我不明白为什么下面的代码打印struct Value而不是int(这意味着转换构造函数转换为Value而不是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>

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

1 个答案:

答案 0 :(得分:1)

我已经尝试过您的代码(仅限Visual Studio版本)。

由于你有一个内置的复制CTOR,我想你的主要等于:

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

编译器已选择使用您的副本CTOR,而不是Value(int)。

将其更改为:

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

打印“int”。