Reputation: 60381
Consider the following code :
#include <iostream>
#include <vector>
#include <type_traits>
// Version A
template<typename T>
void f(const T& x)
{
std::cout<<"Version A"<<std::endl;
}
// Version B
template<template<typename> class T, typename T1>
void f(const T<T1>& x)
{
std::cout<<"Version B"<<std::endl;
}
// Main
int main(int argc, char* argv[])
{
f(double());
f(std::vector<double>()); // <- How to force the use of version B ?
return 0;
}
By default, it will produce :
Version A
Version A
How to force the use of Version B
when the passed type is a template template with the good shape (I can add new versions of f
, I can add std::enable_if
or other C++11 type traits syntax, but if possible I would like to avoid adding an helper class) ?
Upvotes: 8
Views: 164
Reputation: 64223
As Pubby explained in his answer, std::vector is a template with two parameters, therefore your overload function needs to take more template parameters. If you do not want to use variadic templates, then you need to set correct number of parameters :
#include <iostream>
#include <vector>
#include <type_traits>
// Version A
template<typename T>
void f(const T& )
{
std::cout<<"Version A"<<std::endl;
}
// Version B
template<template<typename,typename> class T, typename T1,typename T2>
void f(const T<T1,T2>& )
{
std::cout<<"Version B"<<std::endl;
}
template<typename T>
void baa(const T&)
{
}
// Main
int main()
{
f( double() );
f( std::vector<double>() ); // <- How to force the use of version B ?
}
Upvotes: 1
Reputation: 53047
std::vector
does not take a single typename
parameter, it takes 2! Don't forget the allocator.
Thus, use variadic templates:
template<template<typename...> class T, typename T1>
void f(const T<T1>& x)
{
std::cout<<"Version B"<<std::endl;
}
Now it works as you want.
Upvotes: 11