我有使用CRTP的这些类(代码是虚拟的,仅用于演示问题):
template <class T>
struct IFoo
{
IFoo() {}
IFoo(const char * x) {}
//T & operator=(const char * x){ return *static_cast<T *>(this); } //not working
void Test() { static_cast<T *>(this)->TestInternal(); }
};
struct Bar : public IFoo<Bar>
{
using IFoo<Bar>::IFoo;
Bar(const Bar & b) {}
Bar(const Bar && b) {}
//Bar & operator=(const char * x){ return *this;} //works
void TestInternal(){}
};
代码:
Bar bar = "bar";
bar = "bar2"; //not working if assign operator is in IFoo
如果我在Bar
中使用assign运算符,则上面的代码正常运行。但是,在IFoo
中使用assign运算符则不是,我收到了错误:
error C2280: 'Bar &Bar::operator =(const Bar &)': attempting to reference a deleted function
note: compiler has generated 'Bar::operator =' here
note: 'Bar &Bar::operator =(const Bar &)': function was implicitly deleted because 'Bar' has a user-defined move constructor
为什么?
答案 0 :(得分:3)
最简单的解决方案是using
基本运算符,就像您当前using
基础构造函数一样:
using IFoo<Bar>::operator=;
答案 1 :(得分:0)
之前的回复将使您的代码正常工作。
但我想在CRTP和静态演员中评论一些事情。 我会建议如下: 使构造函数在重复模式上变得私有,以避免使用不当,特别是对于铸件。 然后,您可以从派生的友元类访问构造函数,即使它是非法的,您也可以创建一个包装器。
template <typename T>
struct wrapper {
typedef T type;
};
template <class T>
struct IFoo
{
typedef T temp;
friend class wrapper<temp>::type;
private:
IFoo() {}
IFoo(const char * x) {}
public:
T & operator=(const char * x){ return *static_cast<T *>(this); } //not working
void Test() { static_cast<T *>(this)->TestInternal(); }
};
struct Bar : public IFoo<Bar>
{
//using IFoo<Bar>::IFoo;
using IFoo<Bar>::operator=;
Bar() {}
Bar(const char *x) {}
Bar(const Bar & b) {}
Bar(const Bar && b) {}
//Bar & operator=(const char * x){ return *this;} //works
void TestInternal(){}
};
int main () {
Bar bar = "bar";
bar = "bar";
}