Vincent
Vincent

Reputation: 60381

Force a specific overload when template template

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

Answers (2)

BЈовић
BЈовић

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

Pubby
Pubby

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

Related Questions