I have a class template in which there is a function that takes an argument of the type of the class that inherits the template. I can't seem to find the right syntax to bring this about. For example, if this is my template:
// 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
};
...and this is my class
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...
}
};
...then everything works just fine except that the compiler throws an error saying (in Visual Studio 2013) 'member function declared with "override" does not override a base class member' when it encounters my definition of myClass::move_contents. I can understand why it is unhappy: 'myClass' is not only a 'myTemplate<myStruct>', but a type that jointly inherits both myTemplate<myStruct> and myStruct. What I actually need to do is to declare move_contents in the template so that the argument type is the same as the type of the derived object, in this case 'myClass'. However, I can't think of a way of specifying this in the template declaration.
My working solution is to take move_contents out of the template altogether and define a totally independent move_contents method for each separate derived type. This is all right, but doing this would block off the possibilty of pulling the move constructor and assignment operator back into the template - something I'd love to do if I can ever figure out a way of getting Visual Studio 2013 to export them properly.