Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template as a parameter of function template - deduction fail

Tags:

c++

c++11

c++14

I want to create template like this which can deduce TT class template an T type:

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

template < template <typename> class TT, typename T>
T f(TT<T*> & A ){
    cout << "it works\n";
    return *A[0];
};


int main(){
    vector<int*> v;
    f(v);
    return 0;
}

I have an error (with clang-4.0):

temded2.cpp: In function ‘int main()’:
temded2.cpp:20:21: error: no matching function for call to ‘f(std::vector<int*>&)’
     f<std::vector>(v);
                     ^
temded2.cpp:12:3: note: candidate: template<template<class> class TT, class T> T f(TT<T*>&)
 T f(TT<T*> & A ){
   ^

I think that TT should be equal to std::vector and T should be equal to int, what am i doing wrong ?

like image 215
peterSweter Avatar asked Jan 24 '26 16:01

peterSweter


2 Answers

Your template template-parameter isn't what you think it is. There's more to a std::vector<T> than you think, including default template parameters that you're not accounting for. Luckily, variadic arguments in C++11 will help you solve that problem

#include <iostream>
#include <vector>

template < template <typename, typename...> class TT, typename T, typename... Args>
T f(TT<T*, Args...> & A )
{
    std::cout << __PRETTY_FUNCTION__ << '\n';
    if (A.size() > 0)
        return *(A[0]);
    return T();
};

int main()
{
    std::vector<int*> v;
    f(v);
    return 0;
}

Output

T f(TT<T *, Args...> &) [TT = vector, T = int, Args = <std::__1::allocator<int *>>]

Note the Args above. Because those are missing in your very specific template template-parameter expected arg list, there is no match. As you can see, variadic arguments can solve that problem.

like image 132
WhozCraig Avatar answered Jan 27 '26 06:01

WhozCraig


std::vector is a class template that takes two template parameters:

template<
    class T,
    class Allocator = std::allocator<T>
> class vector;

Your f expects a class template with only one template parameter. So it simply doesn't match.

like image 23
Barry Avatar answered Jan 27 '26 04:01

Barry



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!