含有删除移动构造函数的模糊过载 [英] ambiguous overload with deleted move constructor

查看:149
本文介绍了含有删除移动构造函数的模糊过载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

错误是

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:


  1. int int& ; Test< int> temporary; const Test< int> &

  2. int int rvalue; double rvalue; double&&& ; 测试< double> temporary; const Test< double> &

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

这篇关于含有删除移动构造函数的模糊过载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆