函数的嵌套C++模板参数

bcu*_*ing 20 c++ templates c++11

我想在C++中有一个模板化函数,其中一个模板参数本身就是另一个模板参数的模板.如果这没有任何意义,请使用以下代码打印在类型T上模板化的std :: vector

template <typename T>
void print_vector(std::vector<T> &vec)
{
    for(auto v: vec)
        std::cout << v << " ";
    std::cout << std::endl;
}
...
std::vector<double> vec(5);
...
print_vector(vec);
Run Code Online (Sandbox Code Playgroud)

我想进一步推广除vector之外的STL容器的这个函数.但我不知道如何"嵌套"模板参数,以便容器在类型T上模板化.我尝试了以下但没有成功

template <typename T, template <typename TT> V>
void print_container(V<T> &con)
{
    for(auto c: con)
        std::cout << c << " ";
    std::cout << std::endl;
}
...
std::vector<double> vec(5);
...
print_container(vec);
Run Code Online (Sandbox Code Playgroud)

我确信之前已经回答了这个问题,但我找不到搜索条件来找到答案.

编辑:谢谢@ForEveR,您的回复是对的!对我的问题的所有回答都表明,没有必要将"存储"类型T模板化,以下解决方案足以满足我给出的示例:

template <typename C>
void print_container(C &con)
{
    for(auto v: con)
        std::cout << v << " ";
    std::cout << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,推动这个问题的实际用例有点复杂.该例程需要多个容器,例如带有矩阵和向量类的线性代数示例:

template <typename MATRIX, typename VECTOR>
void mat_vec_multiply(const MATRIX &A, const VECTOR &x, VECTOR &y)
{
    // implement y = A*x;
}
Run Code Online (Sandbox Code Playgroud)

假设MATRIX和VECTOR类都必须在相同的底层存储类上进行模板化(即double,float,int ...).我们的想法是通过明确指定T作为模板参数,我们可以强制执行:

template < typename T,
           template<typename> class MATRIX,
           template<typename> class VECTOR>
void mat_vec_multiply(const MATRIX<T> &A, const VECTOR<T> &x, VECTOR<T> &y)
{
    // implement y = A*x;
}
Run Code Online (Sandbox Code Playgroud)

不幸的是我使用的是CUDA编译器nvcc,它对C++ 11构造没有任何支持(我在我的例子中只使用了C++ 11,因为它不那么详细).所以我不能使用std :: is_same和static_assert,虽然我想我可以轻松地滚动自己的is_same(或使用BOOST).在这种情况下,什么是"最佳实践",我想为存储类强制执行commone模板参数?

For*_*veR 22

std::vector有两个参数,类型和分配器.试试这个

template <typename T, typename Alloc, template <typename, typename> class V>
void print_container(V<T, Alloc> &con)
{
}

print_container(vec);
Run Code Online (Sandbox Code Playgroud)

这将适用于vector,list等,但不适用map,set.

但是,既然你使用了auto你可以使用C++ 11然后你可以这样:

template <typename T, template <typename, typename...> class V, typename... Args>
void print_container(V<T, Args...> &con)
Run Code Online (Sandbox Code Playgroud)

要么

template <template <typename, typename...> class V, typename... Args>
void print_container(V<Args...> &con)
Run Code Online (Sandbox Code Playgroud)

当然,最简单的方法就是做类似的事情

template<typename C>
void print_container(C& con)
Run Code Online (Sandbox Code Playgroud)

可能有一些推断检查,这C真的是容器.

template<typename C>
auto print_container(C& con) -> decltype(con.begin(), void())
Run Code Online (Sandbox Code Playgroud)


Joe*_*oeG 5

你最好不要那样做;只考虑在容器上做模板

template <typename C>
void print_container(const C& container)
{

    for(auto v: container)
        std::cout << v << " ";
    std::cout << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

如果需要函数中的存储类型,可以使用:`typedef typename C::value_type T;