C++ 将特定类型作为泛型参数的STL容器
有什么方法可以使函数以特定类型的容器(比如说C++ 将特定类型作为泛型参数的STL容器,c++,templates,stl,containers,C++,Templates,Stl,Containers,有什么方法可以使函数以特定类型的容器(比如说std::string)作为参数 void foo(const std::container<std::string> &cont) { for(std::string val: cont) { std::cout << val << std::endl; } } void foo(const std::container&cont) { 用于(标准::字符串值:续){ std::c
std::string
)作为参数
void foo(const std::container<std::string> &cont)
{
for(std::string val: cont) {
std::cout << val << std::endl;
}
}
void foo(const std::container&cont)
{
用于(标准::字符串值:续){
std::cout您可以使foo
成为一个函数模板,该模板对容器类型采用a
e、 g
模板
无效foo(施工图C和cont)
{
用于(标准::字符串值:续){
std::cout再加上@songyuanyao的答案,我认为我们可以进一步概括为:
template<template<typename...> typename C, typename ... D>
void foo(const C<D...> &cont)
{
for(const auto& val: cont) {
std::cout << val << std::endl;
}
}
模板
无效foo(施工图C和cont)
{
用于(常数自动和值:续){
std::cout取决于您是否要为其他情况重载foo
// Doesn't participate in overload resolution when not applicable
template<typename Container, typename = std::enable_if_t<std::is_same_v<typename Container::value_type, std::string>>>
void foo(const Container &cont) {
for(std::string val: cont) {
std::cout << val << std::endl;
}
}
// simpler
template<typename Container>
void foo(const Container &cont) {
static_assert(std::is_same_v<typename Container::value_type, std::string>, "Container must contain std::string")
for(std::string val: cont) {
std::cout << val << std::endl;
}
}
您可能想考虑使用迭代器。中间结果可能看起来像
template<typename Iter>
void foo(Iter begin, Iter end) {
using T = decltype(*begin);
std::for_each(begin, end, [] (cons T & t) {
std::out << t << '\n';
}
}
模板
void foo(国际热核实验堆开始,国际热核实验堆结束){
使用T=decltype(*begin);
标准::每个(开始,结束,[])(cons T&T){
是的,它被称为模板函数。;(通常认为传递一对迭代器更好(分别表示容器的开始和结束)。只要迭代器满足函数的要求,它(通常会有一些例外)不管它们是从什么类型的容器中获得的。我认为我们可以进一步推广它。看我的答案。Lars'更好,因为它也适用于C样式的数组。@theWiseBro是的,一般来说这是一个好主意。但我认为OP只是想将它与特定类型一起使用,如std::string
,所以..@theWiseBro说得很对。OP说应该与一个特定类型一起工作。因此,进一步推广它没有任何好处。@theWiseBro我理解你的意思。我不确定OP的初衷,他只是说想要一个特定类型;你可能需要向OP解释一下。:)这并没有将元素类型限制为std::string,所以它不能回答这个问题。@Sasha它是诚然,这不是固定的std::string,而是更一般化的。OP想要使用特定的类型。比如今天他使用std::string,明天他想要使用MyCustomString。这不是更容易维护吗,因为他只需要在单个位置编辑代码?但这并没有说明如何将其限制为std::strin或std::string或MyCustomString元素——querent特别希望采用“具有特定类型的容器”。既然如此,它将接受任何碰巧是模板的类型,那么为什么不只在单个元素上对其进行模板化呢?这更简单,也更一般化——例如,您将采用std::string(又名std::basic_string)作为容器,但不是自定义结构MyCustomString,因此它不是完全通用的。如果函数希望元素为std::string,允许用户传递std::tuple会使使用和维护变得更困难。@Sasha-hmm。我明白你的意思。没错。谢谢提醒!
// Doesn't participate in overload resolution when not applicable
template<typename Container, typename = std::enable_if_t<std::is_same_v<typename Container::value_type, std::string>>>
void foo(const Container &cont) {
for(std::string val: cont) {
std::cout << val << std::endl;
}
}
// simpler
template<typename Container>
void foo(const Container &cont) {
static_assert(std::is_same_v<typename Container::value_type, std::string>, "Container must contain std::string")
for(std::string val: cont) {
std::cout << val << std::endl;
}
}
std::vector<char *> c_strings;
foo(c_strings);
template<typename Iter>
void foo(Iter begin, Iter end) {
using T = decltype(*begin);
std::for_each(begin, end, [] (cons T & t) {
std::out << t << '\n';
}
}
template<typename Iter, typename Callable>
void foo(Iter begin, Iter end, Callable & c) {
std::for_each(begin, end, c);
}