【问题标题】:How to make a vector parameter with a non-specific type?如何制作具有非特定类型的向量参数?
【发布时间】:2019-11-11 06:17:08
【问题描述】:

我的目标是创建一个 C++ 函数,它接受一个向量参数,并且独立于给定向量的类型,将向量的内容一个接一个地打印出来。下面的代码适用于 <int> 类型的向量:

#include <iostream>
#include <vector>

using std::vector;

void PrintVect(vector <int> vect) {
    for (unsigned i = 0; i < vect.size(); i++) {
        std::cout << vect[i];
    }
}

int main() {

    vector <int> nums = {1, 2, 3};

    PrintVect(nums);
}

我应该进行哪些更改才能使其适用于任何类型的矢量?

【问题讨论】:

    标签: c++ function vector types


    【解决方案1】:

    简单:使其成为模板函数。此外,您应该通过 (const) 引用传递向量以避免不必要的复制。

    template<typename T, typename Allocator>
    void PrintVect(const std::vector<T, Allocator> &vect)
    {
        for (const auto &i : vect) std::cout << i;
    }
    

    【讨论】:

    • 当然,这确实假设有一个合适的operator&lt;&lt;() 重载用于将T 流式传输到std::ostream。对于标准库中的基本类型(int 等)和一些(不是全部)类型,这个假设是正确的。对于不正确的类型,这样的解决方案将无法编译。能够对所有类型进行流式传输是没有意义的,因此有必要在需要时特意实现流式传输功能。
    • @Peter 我觉得“打印”这个词暗示了这一点
    【解决方案2】:

    vector&lt;int&gt; 和具有不同元素类型的向量,例如vector&lt;string&gt;,有不同的类型并且不共享一个共同的“超类型”,您可以将其传递给您的“打印各种向量函数”。

    但是,您可以定义一个模板函数,将向量的元素类型作为模板参数;这样,编译器将为您实际使用的每种元素类型自动生成一个专用的打印函数:

    template <typename T>
    void PrintVect(const vector <T> &vect) {
        for (auto val : vect) {
            std::cout << val << " ";
        }
        std::cout << endl;
    }
    
    int main() {
    
        vector <int> nums = {1, 2, 3};
        PrintVect(nums);
    
        vector <string> strings = { "one", "two", "three" };
        PrintVect(strings);
    }
    

    注意void PrintVect(const vector &lt;T&gt; &amp;vect) 中的const&amp;;由于向量没有被修改,传递向量的副本将是多余的;所以参数类型应该是一个常量引用,即const &amp;

    【讨论】:

      【解决方案3】:

      您可以创建一个模板函数,它实际上会为您使用的每个vector&lt;type&gt; 创建一个该函数的副本。

      #include <iostream>
      #include <vector>
      
      // take the vector by reference to not copy the whole vector
      // make it const to promise to not change the vector
      template<typename T>
      void PrintVect(const std::vector<T>& vect) {
          for(const auto& val : vect)
              std::cout << val;
      }
      
      int main() {
          std::vector<int> nums = {1, 2, 3};
      
          PrintVect(nums);
      }
      

      为了使其更易于使用,您可以将您的函数变成operator&lt;&lt; 的重载:

      #include <iostream>
      #include <vector>
      
      template<typename T>
      std::ostream& operator<<(std::ostream& os, const std::vector<T>& vect) {
          for(const auto& val : vect)
              os << val;
          return os;
      }
      
      int main() {
          std::vector<int> nums = {1, 2, 3};
      
          std::cout << nums << "\n";
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-01
        • 1970-01-01
        • 2020-06-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-16
        • 1970-01-01
        相关资源
        最近更新 更多