You need to let your cloning "middleman" class forward constructor arguments, or better (Luc Danton suggested this) use C++11 constructor inheritance.
So, it's easy to do this in C++11, but it's not so easy in C++03 or with a current compiler that doesn't yet support C++11 argument forwarding or constructor inheritance, such as Visual C++10.
One way to do that in C++03, using a helper argument forwarder class, is discussed in my old blog posting "3 ways to mix in a generic cloning implementation". Then the middleman (cloning implementation) class can look like this:
template< class Derived, class Base >
class WithCloningOf
: public progrock::cppx::ConstructorArgForwarder< Base >
{
protected:
virtual WithCloningOf* virtualClone() const
{
return new Derived( *static_cast< Derived const* >( this ) );
}
public:
template< class ArgPack >
WithCloningOf( ArgPack const& args )
: progrock::cppx::ConstructorArgForwarder< Base >( args )
{}
std::auto_ptr< Derived > clone() const
{
return std::auto_ptr< Derived >(
static_cast< Derived* >( virtualClone() )
);
}
};
I discussed the C++03 compatible ConstructorArgForwarder
in earlier blog posting; it can look like this:
template< typename Type >
class ConstructorArgForwarder
: public Type
{
public:
typedef Type Base;
// TODO: remove
virtual ~ConstructorArgForwarder() {}
ConstructorArgForwarder( EmptyArgPack const& )
: Base()
{}
template< class T01 >
ConstructorArgForwarder(
ArgPack< T01 > const& args
)
: Base( args.a01 )
{}
template< class T01, class T02 >
ConstructorArgForwarder(
ArgPack< T01, T02 > const& args
)
: Base( args.a01, args.a02 )
{}
template< class T01, class T02, class T03 >
ConstructorArgForwarder(
ArgPack< T01, T02, T03 > const& args
)
: Base( args.a01, args.a02, args.a03 )
{}
// And more, up to max 12 arguments.
};
It in turn uses an argument pack class ArgPack
(well OK, class template), which can look like this:
enum NoArg {};
template<
class T01 = NoArg, class T02 = NoArg, class T03 = NoArg,
class T04 = NoArg, class T05 = NoArg, class T06 = NoArg,
class T07 = NoArg, class T08 = NoArg, class T09 = NoArg,
class T10 = NoArg, class T11 = NoArg, class T12 = NoArg
>
struct ArgPack;
template<
>
struct ArgPack<
NoArg, NoArg, NoArg, NoArg, NoArg, NoArg,
NoArg, NoArg, NoArg, NoArg, NoArg, NoArg
>
{};
typedef ArgPack<
NoArg, NoArg, NoArg, NoArg, NoArg, NoArg,
NoArg, NoArg, NoArg, NoArg, NoArg, NoArg
> EmptyArgPack;
inline ArgPack<> args() { return ArgPack<>(); }
template<
class T01
>
struct ArgPack<
T01, NoArg, NoArg, NoArg, NoArg, NoArg,
NoArg, NoArg, NoArg, NoArg, NoArg, NoArg
>
{
T01 const& a01;
ArgPack( T01 const& v01 )
: a01( v01 )
{}
};
template< class T01 >
inline ArgPack< T01 >
args( T01 const& a01 )
{
return ArgPack< T01 >( a01 );
}
Disclaimer: erors may just have sneaked in e.g. in copying the code from my blog. However, it worked at the time I posted about it, in May 2010.
Note: As I discuss at in the last of the two above blog postings, about cloning, there three main general ways to do it, and of these the simple macro beats the other two with good margin, for C++03. However, with C++11 the "middleman" approach you've chosen here seems better. The "sideways inheritance" via dominance is just complicated and inefficient, but if you are restricted to C++03, then do consider a simple macro!
Note 2: The last time I suggested doing the practical & sensible thing, I was heavily downvoted (presumably by Reddit kids). Since then, however, I have stopped caring about SO rep points, and in particular downvotes. So, happily, I can now again give good advice, just like in the old Usenet days, just ignoring them downvoter kids' mindless reaction to certain words. :-)