如何编写接受任何类型 std::vector 的函数签名?

How to write function signature for accepting std::vector of any type?

答案 here 有助于显示如何将 std::vector 打印到 std::out。我已经尝试制作一个通用函数来打印任何类型的矢量:

像这样:

  void MyClass::print_vector(const std::vector<auto> vec) {
      for (auto i = vec.begin(); i != vec.end(); ++i)
          std::cout << *i << ' ';
      std::cout << std:: endl;
  }
  std::vector<int> my_vec = {1, 2, 3};
  print_vector(my_vec);

这会按预期构建和运行(至少 std::vector<int>)但会触发构建警告:

warning: use of ‘auto’ in parameter declaration only available with ‘-fconcepts’

在 c++14 中执行此操作的正确方法是什么?

这就是模板应该做的。

template <typename T>
void MyClass::print_vector(const std::vector<T>& vec) {
    for (auto i = vec.begin(); i != vec.end(); ++i)
        std::cout << *i << ' ';
    std::cout << std:: endl;
}

std::vector<int> my_vec = {1, 2, 3};
print_vector(my_vec);

您可以简单地使用自动扣除:

template <typename Container>
void print(const Container& c)
{
   for (const auto& e : c) cout << e << ' ';
   cout << endl;
}

这将接受为其元素定义了 operator<< 的任何类型的任何容器。

还可以使用类型特征 enable/disable 为不同的容器重载。

例如,假设我们有如下定义的类型特征 IsContainer。 然后可以做类似的事情:

template <typename Container,
          typename = enable_if_t<IsContainer<Container, std:::vector>::value>>
void print(const Container& c)
{
   for (const auto& e : c) cout << e << ' ';
    cout << endl;
}

具有 IsContainer 类型特征可用于检查特定容器类型:

template<typename Test, template<typename...> class Ref>
struct IsContainer: std::false_type {};

template<template<typename...> class Ref, typename... Args>
struct IsContainer<Ref<Args...>, Ref>: std::true_type {};

如果您需要在项目中进行更多此类检查,这将很有用。

通过使用 OR'ing,还可以在不复制代码的情况下为不同的容器启用此功能。例如,为 vectorlist 启用打印:

 template <typename Container,
              typename = enable_if_t<
                  IsContainer<Container, std:::vector>::value
               || IsContainer<Container, std::list>::value>>
  void print(const Container& c)
  {
       for (const auto& e : c) cout << e << ' ';
        cout << endl;
  }