template<class T> struct Test {
Test(T&) {}
#ifdef BREAK
Test(T&&) = delete;
#endif
};
void func(Test<int> const&) {}
void func(Test<double> const&) {}
int main()
{
int x = 0;
func(x);
return 0;
}
错误是
error: call of overloaded 'func(int&)' is ambiguous
while clang 3.2 RC2和VC11(如果我用Test(T&&) = delete;
替换private: Test(T&&);
)接受代码。
我看不出哪里应该含糊不清。
这是一个g ++问题吗? (我不知道在gcc错误列表中搜索什么...)
答案 0 :(得分:5)
已删除的构造函数参与重载解析(Are the special member functions always declared?);这是必要的,以便可以使用已删除的构造函数来阻止转换(摘自8.4.3p3):
struct onlydouble {
onlydouble(std::intmax_t) = delete;
onlydouble(double);
};
在重载解析(8.4.3p2)之后的编译过程中,函数删除的执行很晚才发生,因此重载解析无法在删除的基础上区分构造函数。 gcc是正确的,clang和VC11不正确。
请注意,歧义在函数调用表达式func(x)
中,其中参数x
是类型int
的左值,而id func
表示重载集const Test<int> &
和const Test<double> &
的第一个(唯一)参数中的参数类型;可用的转换序列是:
int
左值; int &
; Test<int>
临时的; const Test<int> &
,int
左值; int
右值; double
右值; double &&
; Test<double>
临时的; const Test<double> &
。这两个序列是等级的用户定义的转换序列,因此是不明确的。删除构造函数Test<double>::Test(double &&)
的事实在此阶段无关紧要。
答案 1 :(得分:1)
海湾合作委员会有一个开放的错误:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54425。
CLANG是正确的,GCC需要解决这个问题。