I want to specialize following member function:
class foo {
template<typename T>
T get() const;
};
To other class bar
that depends on templates as well.
For example, I would like bar
to be std::pair
with some template parameters, something like that:
template<>
std::pair<T1,T2> foo::get() const
{
T1 x=...;
T2 y=...;
return std::pair<T1,T2>(x,y);
}
Where T1 and T2 are templates as well. How can this be done? As far as I know it should be possible.
So now I can call:
some_foo.get<std::pair<int,double> >();
The full/final answer:
template<typename T> struct traits;
class foo {
template<typename T>
T get() const
{
return traits<T>::get(*this);
}
};
template<typename T>
struct traits {
static T get(foo &f)
{
return f.get<T>();
}
};
template<typename T1,typename T2>
struct traits<std::pair<T1,T2> > {
static std::pair<T1,T2> get(foo &f)
{
T1 x=...;
T2 y=...;
return std::make_pair(x,y);
}
};
The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.
Function templates. Function templates are special functions that can operate with generic types. This allows us to create a function template whose functionality can be adapted to more than one type or class without repeating the entire code for each type. In C++ this can be achieved using template parameters.
A class template is a template that is used to generate classes whereas a template class is a class that is produced by a template.
Key differences between generics and C++ templates: Generics are generic until the types are substituted for them at runtime. Templates are specialized at compile time so they are not still parameterized types at runtime. The common language runtime specifically supports generics in MSIL.
You can't partially specialize function templates, sorry but those are the rules. You can do something like:
class foo {
...
};
template<typename T>
struct getter {
static T get(const foo& some_foo);
};
template<typename T1, typename T2>
struct getter< std::pair<T1, T2> > {
static std::pair<T1, T2> get(const foo& some_foo) {
T1 t1 = ...;
T2 t2 = ...;
return std::make_pair(t1, t2);
};
and then call it like
getter<std::pair<int, double> >::get(some_foo);
though. You may have to do some messing around with friend
ship or visibility if get
really needed to be a member function.
To elaborate on sbi's suggestion:
class foo {
...
template<typename T>
T get() const;
};
template<typename T>
T foo::get() const
{
return getter<T>::get(*this);
/* ^-- specialization happens here */
}
And now you're back to being able to say
std::pair<int,double> p = some_foo.get<std::pair<int, double> >();
You need to overload your member function for pair, like in
template <T, V> std::pair<T, V> foo::get()
In the general case you will need to be able to disambiguate between the various overloads. In the case disambiguation is easy because pair is templated on 2 types while the original member was templated on T only.
If instead you needed a specialization for, e.g., std::vector, that is for a container with a single parameter template, you have to be careful since given it can be confusing for the compiler to understand if you wish to instantiate the template specialization where the template T is std::vector or the specialization for the overload,
template <T> std::<vector <T> foo::get() const
Your proposed syntax cannot work since you are completely specializing the member function,
template <>
,
but you are leaving out two unspecified types, T1 and T2.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With