ambiguous overload with deleted move constructor

爷,独闯天下 提交于 2019-12-22 03:51:10

问题


g++ 4.6.3 and 4.7.2 fail to compile the following code (in c++0x mode) if BREAK is 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;
}

The error is

error: call of overloaded 'func(int&)' is ambiguous

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.

Is this a g++ issue? (I don't know what to search for in the gcc bug list...)


回答1:


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);
};

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.

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:

  1. int lvalue; int &; Test<int> temporary; const Test<int> &,
  2. int lvalue; int rvalue; double rvalue; double &&; Test<double> temporary; const 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.




回答2:


There is open bug in GCC: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54425.

CLANG is correct, GCC needs to fix this.



来源:https://stackoverflow.com/questions/13703186/ambiguous-overload-with-deleted-move-constructor

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!