运算符=和未在C+中继承的函数+;? 直到我刚刚做了一个测试,我相信C++中只有构造函数不是继承的。但是显然,赋值运算符=不太 原因是什么 是否存在继承赋值运算符的变通方法 操作符+=,操作符-=,…,也是这样吗 是否继承了所有其他函数(除了构造函数/运算符=)

运算符=和未在C+中继承的函数+;? 直到我刚刚做了一个测试,我相信C++中只有构造函数不是继承的。但是显然,赋值运算符=不太 原因是什么 是否存在继承赋值运算符的变通方法 操作符+=,操作符-=,…,也是这样吗 是否继承了所有其他函数(除了构造函数/运算符=),c++,inheritance,operator-overloading,crtp,C++,Inheritance,Operator Overloading,Crtp,事实上,我在做CRTP时遇到了这个问题: template<class Crtp> class Base { inline Crtp& operator=(const Base<Crtp>& rhs) {/*SOMETHING*/; return static_cast<Crtp&>(*this);} }; class Derived1 : public Base<Derived1> { }; class Der

事实上,我在做CRTP时遇到了这个问题:

template<class Crtp> class Base
{
    inline Crtp& operator=(const Base<Crtp>& rhs) {/*SOMETHING*/; return static_cast<Crtp&>(*this);}
};

class Derived1 : public Base<Derived1>
{
};

class Derived2 : public Base<Derived2>
{
};
模板类基类
{
内联Crtp&operator=(const Base&rhs){/*SOMETHING*/;返回static_cast(*this);}
};
类Derived1:公共基
{
};
派生类2:公共基
{
};
有什么办法可以让它工作吗

编辑:好的,我已经解决了这个问题。为什么下面的方法不起作用?如何解决这个问题

#include <iostream>
#include <type_traits>

// Base class
template<template<typename, unsigned int> class CRTP, typename T, unsigned int N> class Base
{
    // Cast to base
    public:
        inline Base<CRTP, T, N>& operator()()
        {
            return *this;
        }

    // Operator =
    public:
        template<typename T0, class = typename std::enable_if<std::is_convertible<T0, T>::value>::type>
        inline CRTP<T, N>& operator=(const T0& rhs)
        {
            for (unsigned int i = 0; i < N; ++i) {
                _data[i] = rhs;
            }
            return static_cast<CRTP<T, N>&>(*this);
        }

    // Data members
    protected:
        T _data[N];
};

// Derived class
template<typename T, unsigned int N> class Derived : public Base<Derived, T, N>
{
};

// Main
int main()
{
    Derived<double, 3> x;
    x() = 3; // <- This is OK
    x = 3;   // <- error: no match for 'operator=' in ' x=3 '
    return 0;
}
#包括
#包括
//基类
模板类基
{
//投靠
公众:
内联基运算符(&O)()
{
归还*这个;
}
//接线员=
公众:
模板
内联CRTP和运算符=(常数T0和rhs)
{
for(无符号整数i=0;ix()=3;//赋值运算符在技术上是继承的;但是,它总是被派生类的显式或隐式定义的赋值运算符隐藏(请参见下面的注释)

(13.5.3分配)分配操作员应由 只有一个参数的非静态成员函数。因为 如果 不是由用户声明的,基类赋值运算符总是 由派生类的复制赋值运算符隐藏

您可以实现一个虚拟赋值操作符,它只需将调用转发给基类
操作符=
,如下所示:

// Derived class
template<typename T, unsigned int N> class Derived : public Base<Derived, T, N>
{
public:
    template<typename T0, class = typename std::enable_if<std::is_convertible<T0, T>::value>::type>
    inline Derived& operator=(const T0& rhs)
    {
        return Base<Derived, T, N>::operator=(rhs);
    }
};
//派生类
派生的模板类:公共基
{
公众:
模板
内联派生运算符和运算符=(常量T0和rhs)
{
返回基::运算符=(rhs);
}
};

赋值运算符在某种程度上是继承的,但在任何给定的 类,如果不提供复制赋值运算符,则编译器 为您生成一个。这意味着您的派生类 有一个赋值运算符:

Derived& operator=( Derived const& );
通常的隐藏规则适用;这将隐藏所有基类 赋值运算符。(如果基类有赋值运算符 使用此签名,派生类将正常继承它。)

  • 您的赋值运算符在技术上是继承的,但随后它被派生类中的默认复制赋值运算符隐藏。该默认复制赋值随后尝试调用基类的复制赋值,该复制赋值由于您使用自己的赋值将其隐藏而不存在

  • 解决这一问题的最明智的方法是不要以不明显的方式使用运算符重载(例如,
    =
    不意味着复制赋值)。在这种情况下,不要使用
    运算符=
    :将其称为
    赋值
    设置
    ,然后它将继承而不会被子复制赋值隐藏

  • 这些运算符是继承的,没有编译器版本,因此它们永远不会像
    operator=
    那样自动隐藏

  • 实际上,只有构造函数不是继承的,我想不出任何其他编译器生成的函数可以像
    operator=
    那样对父函数隐藏某些内容


  • 值得一读斯科特·迈尔斯的书(Efficive C++)第45项也不是说有时=并不意味着=而是复制构造函数。你的
    Derived1
    编译器生成的
    operator=
    shadows基类的
    operator=
    @eq-:我会说@lzprgmr完全重复的可能重复。这有一个很好的解释和解决方法。好的。但我有一个非常奇怪的问题我将隔离问题并编辑我的帖子。虽然技术上正确,但继承的运算符被声明的运算符隐藏(隐式或显式)在派生类中。@eq-:您的测试调用隐式
    派生::运算符=
    ,该运算符反过来调用
    基::运算符=
    。但是,基类版本不能用于从基类对象分配派生类对象,因为它是隐藏的。我假设这就是问题所在,尽管目前有点困难含糊不清。@eq:这个伪运算符赋值的语法是什么?