So if I have
template <class T>
class Object {
// stuff
};
and I receive an instance of object in a function I want to call the constructor of class T.
void foo(Object object) {
auto newT = object::T();
}
Is this possible?
CodePudding user response:
No, you create an instance of a class template by specializing the template. You do this by putting the type you want to use in angle brackets:
void foo(Object<int> object) {
// auto newobj = Object<int>(); this will work
Object<int> newobj; // but this has less cruft
}
or
template <class U>
void foo(Object<U> object) {
// auto newobj = Object<U>();
Object<U> newobj {object};
}
Remember that the symbol T
does not exist outside the template definition. To get a "real" Object
you have to put in an actual type. I chose int
but you will probably use something else.
Of course, this will only work if the stuff
contains a corresponding constructor:
template <class T>
class Object {
// stuff
public:
Object(); // often implicit but sometimes not
Object(Object<T> const &i) = default;
// more stuff
};
CodePudding user response:
One solution is to store the template variable in the Object
class (this only takes up memory at compile-time):
template <class T>
class Object {
// stuff
public:
using inner_type = T;
};
Then you can access the template type like so:
template <class Obj>
void foo(Obj object) {
typename Obj::inner_type newT;
}
If you don't want to add inner_type
to Object
then you could make the following type trait:
template <class T>
struct tag {
using type = T;
};
template <class>
struct inner;
template <template <class> class S, class T>
struct inner <S<T>> : tag<T> {};
template <typename T>
using inner_t = inner<T>;
Which you can then use like so:
template <class Obj>
void foo(Obj object) {
inner_t<Obj> newT;
}