Templates 用于接受派生对象类型的参数的模板语法
我有一个类模板,其中有一个函数,它接受继承模板的类类型的参数。我似乎找不到正确的语法来实现这一点。例如,如果这是我的模板:Templates 用于接受派生对象类型的参数的模板语法,templates,inheritance,c++11,polymorphism,Templates,Inheritance,C++11,Polymorphism,我有一个类模板,其中有一个函数,它接受继承模板的类类型的参数。我似乎找不到正确的语法来实现这一点。例如,如果这是我的模板: // A template to promote a simple C-style struct, T_C, // to a C++ class 'T' with constructors, destructors, // copy and move assignment operators. template <typename T_C> class my
// A template to promote a simple C-style struct, T_C,
// to a C++ class 'T' with constructors, destructors,
// copy and move assignment operators.
template <typename T_C> class myTemplate
{
// We could in principle create templated copy and move
// constructors and assignment operators, but they'd be
// implicitly deleted by the compiler unless we explicitly defaulted
// them: see
// http://stackoverflow.com/questions/25246573/copy-assignment-operator-defined-in-template-being-deleted-by-compiler.
// Explicitly defaulting them works well if the template is
// contained in an all-header library. However, on including
// the template-derived classes into a DLL in Visual Studio 2013
// it was found that, even when all the other methods
// in a class were properly exported, the defaulted
// template methods were not. There may be a workaround for
// this, but in the scheme of things it was thought easier
// just to dispense with the templated operators and to
// create copy and move assignment operators, as well as the
// corresponding constructors, for each derived type.
//
// We can at least simplify things a little, and force some
// consistency upon our various class definitions,
// by insisting that every relevant class defines the
// functions listed, which can then be called from the
// constructors and assignment operators to make them a bit
// more manageable.
// Tidy up all pointers etc. and return all buffers to a safe state
virtual void clear() = 0;
protected:
// Construct a 'T' from a T_C:
virtual void construct_contents(const T_C &source) = 0;
// Deep copy the contents of a T_C to a 'T'
virtual void copy_contents(const T_C &source) = 0;
// Move the contents of one object to another: for use in both the move constructor
// and the move assignment operator:
virtual void move_contents(myTemplate<T_C> &&source) = 0;
// For sure this is wrong, but I can't figure out
// what the right argument type should be
};
virtual T_C * baseObject() = 0;
//一个用于升级简单C风格结构的模板,T\u C,
//用构造函数、析构函数生成C++类的t’
//复制和移动赋值运算符。
模板类myTemplate
{
//原则上,我们可以创建模板复制和移动
//构造函数和赋值运算符,但它们是
//由编译器隐式删除,除非我们显式默认
//他们:看到了吗
// http://stackoverflow.com/questions/25246573/copy-assignment-operator-defined-in-template-being-deleted-by-compiler.
//如果模板是
//包含在所有标头库中。但是,在
//在Visual Studio 2013中将模板派生类导入DLL
//结果发现,即使所有其他方法
//在正确导出的类中,默认
//模板方法不可用。可能存在解决方法
//这一点,但在计划中,人们认为更容易做到
//只是为了省去模板化的操作符
//创建复制和移动指定操作符,以及
//每个派生类型对应的构造函数。
//
//我们至少可以把事情简化一点,强迫一些人去做
//我们的各种类定义的一致性,
//通过坚持每个相关类定义
//列出的函数,然后可以从
//构造函数和赋值运算符,使它们稍微
//更容易管理。
//整理所有指针等,并将所有缓冲区恢复到安全状态
虚空清除()=0;
受保护的:
//从T_C构造一个“T”:
虚空构造内容(常量和源)=0;
//将T_C的内容深度复制到“T”
虚拟无效副本内容(常量和源)=0;
//将一个对象的内容移动到另一个对象:用于移动构造函数和
//和移动分配操作符:
虚拟空移动内容(myTemplate&&source)=0;
//当然这是错误的,但我不明白
//正确的参数类型应该是什么
};
…这是我的课
class myClass : public myStruct, public myTemplate<myStruct>
{
public:
// Default constructor
myClass() {}
// Copy constructor taking basic C struct
myClass(const myStruct &source)
{ construct_contents(source); }
// Copy constructor taking this promoted C++ class
myClass(const myClass &source)
{ construct_contents(source); }
// Copy assignment operator taking basic C struct
MyClass & operator=(const myStruct &source)
{
copy_contents(source);
return *this;
}
// Copy assignment operator taking this promoted C++ class
MyClass & operator=(const myClass &source)
{
copy_contents(source);
return *this;
}
// Move constructor taking this promoted C++ class
myClass(myClass &&source)
{
move_contents(std::move(source));
}
// Move assignment operator taking this promoted C++ class
myClass & operator=(myClass &&source)
{
if (this != &source)
{
clear();
move_contents(std::move(source));
}
return *this;
}
// Destructor
~myClass()
{
clear();
}
// Various getters and setters for the data fields of myStruct
// ....
virtual void clear() override
{
// Stuff...
}
protected:
virtual void construct_contents(const myStruct &source) override
{
// Stuff...
}
virtual void copy_contents(const myStruct &source) override
{
// Stuff...
}
virtual void move_contents(myClass &&source) override
{
// Stuff...
}
};
class myClass:public myStruct,public myTemplate
{
公众:
//默认构造函数
myClass(){}
//使用基本C结构复制构造函数
myClass(const myStruct和source)
{构造内容(源);}
//复制构造函数采用此改进C++类
myClass(常量myClass和源)
{构造内容(源);}
//采用基本C结构的复制赋值运算符
MyClass和运算符=(const myStruct和source)
{
复制内容(来源);
归还*这个;
}
//复制赋值操作符采用此改进C++类
MyClass和运算符=(常量MyClass和源)
{
复制内容(来源);
归还*这个;
}
//移动构造函数采用此改进C++类
myClass(myClass&&source)
{
移动内容(标准::移动(源));
}
//移动分配运算符采用此改进C++类
myClass和运算符=(myClass和源代码)
{
if(此!=&source)
{
清除();
移动内容(标准::移动(源));
}
归还*这个;
}
//析构函数
~myClass()
{
清除();
}
//myStruct数据字段的各种getter和setter
// ....
虚拟void clear()重写
{
//东西。。。
}
受保护的:
虚空构造内容(const myStruct&source)重写
{
//东西。。。
}
虚拟无效副本内容(const myStruct&source)覆盖
{
//东西。。。
}
虚拟空移动内容(myClass&&source)覆盖
{
//东西。。。
}
};
…然后一切正常,除了编译器在遇到myClass::move_内容的我的定义时抛出一个错误,即(在Visual Studio 2013中)“用“override”声明的成员函数不重写基类成员”。我可以理解为什么它不高兴:“myClass”不仅是一个“myTemplate”,而且是一个联合继承myTemplate和myStruct的类型。我实际上需要做的是在模板中声明move_内容,以便参数类型与派生对象的类型相同,在本例中为“myClass”。但是,我想不出在模板声明中指定它的方法
我的工作解决方案是将move_内容完全从模板中移除,并为每个单独的派生类型定义一个完全独立的move_内容方法。这没关系,但这样做会阻止将移动构造函数和赋值操作符拉回到模板中的可能性——如果我能找到一种方法让Visual Studio 2013正确导出它们,我很乐意这样做 模板参数是
myStruct
,因此该方法需要类型为myTemplate
的参数,而不是myClass
使用以下命令声明您的方法:
virtual void move_contents(myTemplate<myStruct> &&source) override
{
// Stuff...
}
virtual void move\u内容(myTemplate&source)覆盖
{
//东西。。。
}
我将接受@quantdev的答案,因为他让我走上了正确的道路,但以下是最终奏效的方法
在我的原始代码片段(请参见上面的问题)中,我在模板中插入了一个额外的公共虚拟函数:
// A template to promote a simple C-style struct, T_C,
// to a C++ class 'T' with constructors, destructors,
// copy and move assignment operators.
template <typename T_C> class myTemplate
{
// We could in principle create templated copy and move
// constructors and assignment operators, but they'd be
// implicitly deleted by the compiler unless we explicitly defaulted
// them: see
// http://stackoverflow.com/questions/25246573/copy-assignment-operator-defined-in-template-being-deleted-by-compiler.
// Explicitly defaulting them works well if the template is
// contained in an all-header library. However, on including
// the template-derived classes into a DLL in Visual Studio 2013
// it was found that, even when all the other methods
// in a class were properly exported, the defaulted
// template methods were not. There may be a workaround for
// this, but in the scheme of things it was thought easier
// just to dispense with the templated operators and to
// create copy and move assignment operators, as well as the
// corresponding constructors, for each derived type.
//
// We can at least simplify things a little, and force some
// consistency upon our various class definitions,
// by insisting that every relevant class defines the
// functions listed, which can then be called from the
// constructors and assignment operators to make them a bit
// more manageable.
// Tidy up all pointers etc. and return all buffers to a safe state
virtual void clear() = 0;
protected:
// Construct a 'T' from a T_C:
virtual void construct_contents(const T_C &source) = 0;
// Deep copy the contents of a T_C to a 'T'
virtual void copy_contents(const T_C &source) = 0;
// Move the contents of one object to another: for use in both the move constructor
// and the move assignment operator:
virtual void move_contents(myTemplate<T_C> &&source) = 0;
// For sure this is wrong, but I can't figure out
// what the right argument type should be
};
virtual T_C * baseObject() = 0;
在我对myClass的定义中,我将其改写如下:
virtual myStruct * baseObject() override { return static_cast<myStruct *>(this); }
virtualmystruct*baseObject()重写{return static_cast(this);}
这是因为myClass继承了myStruct,所以任何myClass对象的“This”指针都可以强制转换为myStruct*
然后,在