clang和gcc在以下代码的行为上有所不同:
行为保持不变。
struct foo
{
foo(int);
};
struct waldo
{
template <typename T>
operator T();
};
int main()
{
waldo w;
foo f{w};
}
这段代码被clang接受,调用了foo(int)
构造函数。然而,gcc抱怨foo(int)
构造函数和隐式生成的拷贝和移动构造函数之间存在歧义:
test.cpp: In function 'int main()':
test.cpp:15:12: error: call of overloaded 'foo(<brace-enclosed initializer list>)' is ambiguous
foo f{w};
^
test.cpp:15:12: note: candidates are:
test.cpp:3:5: note: foo::foo(int)
foo(int);
^
test.cpp:1:8: note: constexpr foo::foo(const foo&)
struct foo
^
test.cpp:1:8: note: constexpr foo::foo(foo&&)
谁是正确的?
有趣的是,如果将foo f{w}
更改为foo f(w)
(注意从大括号到圆括号的更改),gcc和clang都会给出错误。这让我希望gcc对上面的示例(即给出错误)的行为是正确的,否则()
和{}
初始化形式之间将存在奇怪的不一致性。
编辑:根据的建议,我尝试delete
foo
的复制构造函数:
struct foo
{
foo(int);
foo(const foo&) = delete;
};
行为保持不变。
int
,也可以将其转换为Foo
,因此这看起来确实是有歧义的。不过,尝试删除或默认复制/移动构造函数,然后进行比较。 - Kerrek SB