c++ - 绕过自动生成的赋值运算符(VS bug?)

标签 c++ visual-studio-2008 templates compiler-errors assignment-operator

采用以下代码:

class Foo
{
    Foo const& operator =(Foo const& rhs); // disallow
};

struct Bar
{
public:
    Foo foo;

    template <class T>
    T const& operator =(T const& rhs) { return rhs; }
};

struct Baz : public Bar {
    using Bar::operator =;
};

int main()
{
    Baz b1, b2;
    b1 = b2;
}

编译失败是因为将使用自动生成的 Bar::operator = 赋值运算符,它会尝试使用私有(private)的 Foo::operator =。还行吧。所以我在 Bar 中添加了一个额外的成员:

Bar const& operator =(Bar const& b) { return Bar::operator=<Bar>(b); }

现在我们有一个不同的问题。我有两个重载,只能使用其中一个。我正在传递一个 Baz const&。我所知道的关于 C++ 的一切都表明这应该最终使用非模板版本,因为首先选择匹配的非模板。这似乎也是 gcc 正在做的事情。 Visual Studio 似乎不同意:

error C2666: 'Bar::operator =' : 2 overloads have similar conversions
    could be 'const Bar &Bar::operator =(const Bar &)'
    or       'const T &Bar::operator =<Baz>(const T &)'
    with
    [
        T=Baz
    ]
    while trying to match the argument list '(Baz, Baz)'

我很想在这里相信 gcc,这既是因为我对 C++ 的理解证实了这一点,也是因为当 gcc 不同意 Visual Studio 时我通常支持它,但我并不像我对这个那样担心:

在我的非最小示例中,老实说,我根本不需要默认生成的赋值运算符。我对模板运算符(operator)完成这项工作非常满意 - 它会正确完成。但是,由于 VS 提示模板与自动生成的赋值运算符之间存在冲突,我实际上根本无法使该模板工作。我已经尝试了以下所有方法:

  1. 将赋值运算符设为私有(private)且未实现(不起作用,因为“并非所有重载都是可访问的”)
  2. 创建它(导致上述错误)
  3. 将其遗漏(导致上述默认生成的赋值运算符的错误)
  4. 为该类型创建模板的特化,从而精确匹配默认赋值运算符(根据编译器,这显然是非法的)

有没有人对我如何解决这个问题有什么好主意?不幸的是,我的 VS 版本不支持自动生成的赋值运算符的 C++0x“删除”覆盖,因此这不是一个选项,而且我想不出任何其他方法来解决此错误。

最佳答案

在解析两个版本的赋值运算符时出现的歧义是由 Baz 定义中的“using Bar::operator =”引起的。

无论是在 Bar 中隐式定义还是显式定义,非模板版本都采用参数“const Bar&”,它与“Baz”不完全匹配,这是与模板进行明确解析所需要的。

解决这个问题的方法有很多,但真正的解决方案将取决于真正的来源。

为了修正这个例子,我会做这些事情:

o 防止自动生成 const Bar& operator =(const Bar& b) 因为它将使用 Foo 的赋值运算符。您已经尝试添加到 Bar 的定义中的内容将起作用:

Bar const& operator =(Bar const& b) {
    return Bar::operator=<Bar>(b); 
}

o 在 Baz 的定义中使用 Bar::operator = 需要去。将其替换为包装 Bar::operator= 的函数。如:

template <class T>
const T& operator =(const T& rhs) {
    return Bar::operator =(rhs); 
}

(当然,普通代码总是会返回 *this —— 一个 Bar&,而不是参数的类型。)

关于c++ - 绕过自动生成的赋值运算符(VS bug?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11198979/

相关文章:

php - 使用正则表达式解析嵌套的 IF 语句

c++ - 如何使用 get std::bind 之类的行为

c++ - 还需要最终确定的 CRTP 中间类

电子邮件 ID 的正则表达式,在 @ 符号后只允许特定数量的点 (1-5)

c++ - 模板 vector

c++ - 强制 VSProps 设置覆盖项目设置

c++ - Visual Studio 2008 c++ 智能设备平台

css - 无法识别 django css 文件 - 配置错误?

c++ - 如何在没有 sizeof 的情况下最好地防止自定义断言中出现未使用的变量警告?

c++ - 在 C++ 中返回一个数组