如何保留模板模板(+模板)参数的内部模板未指定

时间:2014-08-12 15:42:56

标签: c++ template-templates

如何编译以下代码?

#include "vector"

template<
    template<class> class Container
> Container<int> f(int i) {
    return Container<int>{i};
}

int main() {
    return f<std::vector>(1)[0];
}

GCC-4.8.2抱怨:

error: no matching function for call to 'f(int)'
note: template<template<class> class Container> Container<int> f(int)

实际问题是如何允许调用者指定在函数内部使用哪个特征线性代数求解器(例如http://eigen.tuxfamily.org/dox/classEigen_1_1BiCGSTAB.html),而代码中的唯一更改是注释掉另一行:

Eigen::BiCGSTAB<Eigen::SparseMatrix<Scalar_T>> solver;
//Eigen::ConjugateGradient<Eigen::SparseMatrix<Scalar_T>> solver;
//Eigen::SimplicialCholesky<Eigen::SparseMatrix<Scalar_T>> solver;

目前该功能以:

开头
template<
    template<class> class Eigen_Solver_T,
    class Scalar_T
> std::vector<Scalar_T> solve(...)

,我不希望调用者也必须给Eigen :: SparseMatrix,或者只给予

Eigen::BiCGSTAB<Eigen::SparseMatrix<Scalar_T>>

作为模板参数。

2 个答案:

答案 0 :(得分:3)

您需要了解您拥有的模板类型。在这种情况下,std::vector两个类型参数:

template <typename T, template <typename, typename> class C>
C<T> foo()
{
    return C<T>();
}

更一般地说,您可能希望使用可变参数签名,即使对于非可变参数模板也是允许的:

template <typename T, template <typename...> class C>
C<T> bar()
{
    return C<T>();
}

用法:

foo<int, std::vector>();    // OK, returns std::vector<int, std::allocator<int>>
bar<int, std::vector>();    // OK, ditto
bar<int, std::set>();       // also OK

答案 1 :(得分:0)

您不能使用std::vector作为函数的模板参数,因为std::vector定义为:

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

但是,您可以使用C ++ 11的模板别名功能来实现目标。

#include <vector>

template<
    template<class> class Container
> Container<int> f(int i) {
    return Container<int>{i};
}

template <typename T>
using MyVector = std::vector<T>;

int main() {
    return f<MyVector>(1)[0];
}