奇怪的行为variadic论证模板

时间:2017-02-03 01:31:12

标签: c++ c++11 templates variadic-templates

我自己编写了一个接受通用STL容器的函数,并提出了这个设计:

template<template<class, class...> class C,
         class... A,
         class T = typename C<A...>::value_type>
void wrong( std::vector<C<T, A...>>& indexes, std::vector<T>& resultSet ) {
    resultSet.push_back(indexes[0][0]);
}

这是我的第一次尝试,这是明显错误但是有效,所以我跳过了然后我在代码审查中发现了错误并写了以下哪个更正确

template<template<class...> class C,
         class... A,
         class T = typename C<A...>::value_type>
void correct( std::vector<C<A...>>& indexes, std::vector<T>& resultSet ) {
    resultSet.push_back(indexes[0][0]);
}

让我们说上面的代码用于以下内容:

int main()
{
    std::vector<int> v1 {1,2}, v2{3,4};
    std::vector<std::vector<int>> sets {v1, v2};
    std::vector<int> r;

    wrong(sets, r);
    std::cout << r.back() << std::endl;
    r.clear();

    correct(sets, r);
    std::cout << r.back() << std::endl;

}

编译我得到相同(和预期)的行为,但我觉得第一个错误的函数应该失败,因为&#34; C&#34; type有三种类型作为参数: int,int,Allocator 。 第二个的行为符合我对模板的理解。

问题是:上面的模板演绎是怎么回事?

1 个答案:

答案 0 :(得分:1)

我们可以推导出C = std::vector,因为它可能需要1个或更多模板参数(在本例中为intAllocator)。然后我们推断出A必须是与向量一起使用的分配器。最后T被推断为int(在这种情况下我们不使用默认参数)。如果我们写出来,我们得到

void wrong(std::vector<std::vector<int, Allocator>>& indexes, std::vector<int>& resultSet);

我们可以看到它很好,可以用我们的参数调用。

参数包A被推导为Allocator的单个值,因为如果我们删除std::vector的第一个模板参数,我们只剩下一个其他参数{{1演绎到。