[英]Nested C++ template parameters for functions
我想在 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 )。 在这种情况下,我想强制执行存储类的通用模板参数的“最佳实践”是什么?
std::vector
有两个参数,类型和分配器。 试试这个
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())
你最好不要那样做; 只考虑在容器上做模板
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;
我不确定我是否理解你想要的,但你可以试试这个:
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
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.