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) ?
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.
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 ?
}
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