Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将特定类型作为泛型参数的STL容器_C++_Templates_Stl_Containers - Fatal编程技术网

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);
}