模板作为功能模板的参数 - 演绎失败

时间:2017-02-04 18:16:21

标签: c++ c++11 c++14

我想创建这样的模板,它可以推断TT类模板和T类型:

#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;
}

我有一个错误(使用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 ){
   ^

我认为TT应该等于std :: vector而T应该等于int,我做错了什么?

3 个答案:

答案 0 :(得分:4)

std::vector是一个类模板,它带有两个模板参数:

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

您的f期望只有一个模板参数的类模板。所以它根本不匹配。

答案 1 :(得分:4)

您的模板模板参数不是您认为的那样。 std::vector<T>比您想象的更多,包括您未考虑的默认模板参数。幸运的是,C ++ 11中的可变参数将帮助您解决该问题

#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;
}

<强>输出

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

请注意上面的Args。因为您的特定模板模板参数预期arg列表中缺少那些,所以没有匹配项。如您所见,可变参数可以解决该问题。

答案 2 :(得分:2)

由于vector是一个带有两个模板参数的模板,一个用于元素类型,一个用于分配器,

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

您的temlate参数B还需要两个模板参数,因此函数如下所示:

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

现在功能正常。 live demo