1

如何使以下代码编译?

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

作为模板参数。

4

2 回答 2

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
于 2014-08-12T15:46:44.763 回答
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];
}
于 2014-08-12T15:54:34.633 回答