问题描述
g ++ 4.6.3和4.7.2无法编译以下代码(在c ++ 0x模式下)。
g++ 4.6.3 and 4.7.2 fail to compile the following code (in c++0x mode) if BREAKis defined.
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
$ b b
而clang 3.2 RC2和VC11(如果我替换 Test(T&&)= delete;
with private:Test(T& &);
while clang 3.2 RC2 and VC11 (if I replace Test(T&&) = delete;
with private: Test(T&&);
) accept the code.
我无法看到哪里应该有歧义。
I can't see where that should be ambiguous.
这是一个g ++问题吗? (我不知道在gcc bug列表中搜索什么...)
Is this a g++ issue? (I don't know what to search for in the gcc bug list...)
推荐答案
删除的构造函数参与重载分辨率();这是必要的,以便可以使用删除的构造函数来防止转换(摘自8.4.3p3):
Deleted constructors participate in overload resolution (Are the special member functions always declared?); this is necessary so that one can use deleted constructors to prevent conversions (excerpted from 8.4.3p3):
struct onlydouble {
onlydouble(std::intmax_t) = delete;
onlydouble(double);
};
强制执行函数删除在编译过程中非常晚,在重载解析(8.4.3p2)和所以重载分辨率不能在删除的基础上区分构造函数。 gcc是正确的,clang和VC11不正确。
Enforcement of function deletion comes very late in the compilation process, after overload resolution (8.4.3p2) and so overload resolution cannot distinguish between constructors on the basis of deletion. gcc is correct and clang and VC11 are incorrect.
注意,模糊度在函数调用表达式 func(x)
,其中参数 x
是类型 int
和id func
表示在 const Test< int>的第一个(仅)参数中的参数类型的重载集合。 &
和 const Test< double> &
;可用的转换序列是:
Note that the ambiguity is in the function call expression func(x)
, where the argument x
is an lvalue of type int
and the id func
denotes an overload set with parameter types in the first (only) parameter of const Test<int> &
and const Test<double> &
; the available conversion sequences then are:
-
int
int&
;Test< int>
temporary;const Test< int> &
, -
int
int
rvalue;double
rvalue;double&&&
;测试< double>
temporary;const Test< double> &
。
int
lvalue;int &
;Test<int>
temporary;const Test<int> &
,int
lvalue;int
rvalue;double
rvalue;double &&
;Test<double>
temporary;const Test<double> &
.
这两个序列是用户定义的等级转换序列, 。在此阶段,删除构造函数 Test< double> :: Test(double&&&)
不相关。
The two sequences are user-defined conversion sequences of equal rank, and so are ambiguous. The fact that the constructor Test<double>::Test(double &&)
is deleted is irrelevant at this stage.
这篇关于含有删除移动构造函数的模糊过载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!