简体   繁体   中英

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

The answer here helpfully shows how to print a std::vector to std::out . I've tried making a generic function for printing vectors of any kind:

something like this:

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

This builds and runs as expected (at least for std::vector<int> ) but does trigger a build warning:

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

what is the proper way to do this in c++14?

This is what templates supposed to do.

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

You can go simple and use auto deduction:

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

This will accept any container for any type with defined operator<< for its elements.

One could also use type traits to enable/disable overloads for different containers.

For example, lets say we have type traits IsContainer defined as below. Then one could do something like:

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

with IsContainer type traits available to check for specific container type:

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

This would be usable if you'd need more such checks in your project.

By using OR'ing one could also enable this for different containers with not replicating the code. For example to enable printing for vector and list :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM