我想在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);
我想进一步推广除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);
我确信之前已经回答过,但我找不到搜索字词来找到答案。
编辑:谢谢@ForEveR,您的回复是正确的!对我的问题的所有回答都观察到没有必要将“存储”类型T模板化,以下解决方案对于我给出的示例是足够的:
template <typename C>
void print_container(C &con)
{
for(auto v: con)
std::cout << v << " ";
std::cout << std::endl;
}
不幸的是,推动这个问题的实际用例有点复杂。该例程需要多个容器,例如带有矩阵和向量类的线性代数示例:
template <typename MATRIX, typename VECTOR>
void mat_vec_multiply(const MATRIX &A, const VECTOR &x, VECTOR &y)
{
// implement y = A*x;
}
假设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;
}
不幸的是我使用的是CUDA编译器nvcc,它对C ++ 11构造没有任何支持(我在我的例子中只使用了C ++ 11,因为它不那么详细)。所以我不能使用std :: is_same和static_assert,虽然我想我可以轻松地滚动自己的is_same(或使用BOOST)。在这种情况下,什么是“最佳实践”,我想为存储类强制执行commone模板参数?
答案 0 :(得分:20)
std::vector
有两个参数,type和allocator。
试试这个
template <typename T, typename Alloc, template <typename, typename> class V>
void print_container(V<T, Alloc> &con)
{
}
print_container(vec);
这适用于vector
,list
等,但不适用于map
,set
。
但是,由于你使用auto
,你可以使用C ++ 11,然后就可以了:
template <typename T, template <typename, typename...> class V, typename... Args>
void print_container(V<T, Args...> &con)
或
template <template <typename, typename...> class V, typename... Args>
void print_container(V<Args...> &con)
当然,最简单的方法是做一些像
这样的事情template<typename C>
void print_container(C& con)
可能有一些推断检查,C
实际上是容器。
template<typename C>
auto print_container(C& con) -> decltype(con.begin(), void())
答案 1 :(得分:3)
你最好不要那样做;考虑只是模板化容器
template <typename C>
void print_container(const C& container)
{
for(auto v: container)
std::cout << v << " ";
std::cout << std::endl;
}
如果你需要函数中存储的类型,你可以使用:`typedef typename C :: value_type T;
答案 2 :(得分:2)
我不确定我理解你想要什么,但你可以试试这个:
template <typename V>
void print_vector(V &vec)
{
for(auto v: vec)
std::cout << v << " ";
std::cout << std::endl;
}
...
std::vector<double> vec(5);
...
print_vector(vec);
这里的要点是,通常您不需要像template < template V< typename T> >
这样的构造,因为整个模板template V< typename T>
可以推广到V
类型。