Class constructor with template type without arguments
It is possible for a normal C ++ function to have template parameters that are not in the argument list:
template<typename T>
T default_construct()
{
return T();
}
and call it with
some_type x = default_construct<some_type>();
Although the type I am using is not in the argument list, I can still pass it to the function. Now I want to do this in the constructor of the class:
struct Base;
template<typename T>
Base* allocate()
{
return new T; //Assume T derives from Base...
}
struct factory {
template<typename T>
factory()
: func(allocate<T>)
{}
std::tr1::function<Base*()> func;
};
but I can't find a way to provide a parameter to a constructor when I want to build an instance factory
.
Is there a way to do this without turning the class into a templated class, or sending some unused object T
to the constructor?
source to share
No, there is no way to do it. A note in 14.8.1/5
the Standard explains why
[Note: Because the explicit template argument list follows the function template name, and since member function templates and constructor member function templates are called without using the function name, there is no way to provide an explicit template argument list for these functional templates. ]
Of course, it doesn't have to be the object T
you are sending. It can be any object that has T
, encoded in its type
template<typename T> struct type2type { };
struct factory {
template<typename T>
factory(type2type<T>)
: func(allocate<T>)
{}
std::tr1::function<Base*()> func;
};
factory f((type2type<Foo>()));
source to share
The labels and wrang-wrang answers are good. As another possibility, you might consider declaring all of your (non-copies) constructors private or protected, and creating one or more static member function templates factory create<T>()
. Then to define a factory instance instead
factory<SomeType> f; // 1 (doesn't compile)
You write
factory f(factory::create<SomeType>()); // 2
Obviously it's not quite as pretty as (1), but IMHO is a little clearer than using type tags. (The compiler will exclude the copy in practice.)
By the way, is there a reason why you couldn't just make a factory
template template? Then the syntax from (1) will compile. (This would mean, however, that factories of different types cannot be assigned to each other.)
source to share