【问题标题】:How to pass a dynamic object of the type array to a function?如何将数组类型的动态对象传递给函数?
【发布时间】:2018-12-04 06:26:42
【问题描述】:

我想将一个动态大小标准和 typename 类型的数组传递给一个函数。

我不知道该怎么做。为什么我不能只接受对对象数组的引用?

我试过的代码:

#include <iostream>
#include <array>

using namespace std;

template <typename T>
void showArrays(void *myArrayPointer, int size, T type) {
    array<T, size> myArray = myArrayPointer;
    for (int i = 0; i < size; i++) {
        cout << myArray.at(i) << " \n";
    }
}

int main()
{
    array<int,6> myArray = { 1,2,3,4,5,6 };
    cout << "The array is \n";
    showArrays(&myArray,6,0);

    return 0;
}

但我仍然得到了 Size 的预期编译时常量表达式。 我的函数头也不是很漂亮。但是如果不传递通用指针或创建大小是属性的类数组的模板,我无法找到一种动态大小的方法。

【问题讨论】:

    标签: c++ arrays


    【解决方案1】:

    这里根本没有理由使用void*std::array 的元素类型和大小在编译时是已知的,您可以使用模板捕获它们。

    template<typename T, std::size_t N>
    void print_arry(const std::array<T, N>& arr)
    {
        for (const auto& e : arr)
            std::cout << e << "\n";
    }
    

    将捕获任何std::array 并打印其元素,只要它们具有重载的operator &lt;&lt;。你也可以使用T作为元素类型,N作为函数内部数组的大小,这样你就可以编写一个累加函数,比如

    template<typename T, std::size_t N>
    T print_arry(const std::array<T, N>& arr)
    {
        if (N == 0)
            return 0;
        T accum = arr[0];
        for (std::size_t i = 1; i < N; ++i)
            accum += arr[i];
        return accum;
    }
    

    【讨论】:

      【解决方案2】:

      如果你想要一个函数模板,其中类型是模板参数,但大小是运行时属性(如果你想避免二进制膨胀,这可能是有意义的),那么你需要这样的东西:

      template <typename T>
      void showArrays(T* p, int n) {
          for (int i = 0; i < n; ++i) {
              std::cout << p[i] << '\n';
          }
      }
      
      int main() {
          std::array<int, 6> myArray = { 1,2,3,4,5,6 };
          std::cout << "The array is \n";
          showArrays(myArray.data(), 6);  // or use myArray.size()
      }
      

      您也可以将模板重复用于其他类型的连续数组:

      float a[] = { 1.1, 2.2, 3.3, 4.4 };
      showArrays(a, 4);        // full array
      showArrays(a + 1, 2);    // just the middle two
      
      std::vector<long> v = /* ... */;
      showArrays(v.data(), v.size());
      
      std::string s = "hello world";
      showArrays(s.data() + 6, 5);
      

      注意T 是一个模板 参数而不是函数参数。进一步注意,我们从不为参数指定参数:那是因为参数是推导出来的。如果您确实想传递一个 void 指针,就像您在示例中所做的那样,那么您将无法从函数调用中推断出模板参数,您必须明确指定它:

      template <typename T>
      void showArrays(void* p, int n) {
      //              ^^^^^
          for (int i = 0; i < n; ++i) {
              std::cout << static_cast<T*>(p)[i] << '\n';
              //           ^^^^^^^^^^^^^^^^^^
              //           cast to object pointer,
              //           note that "T" shows up in your code now!
          }
      }
      
      showArrays<int>(myArray.data(), myArray.size());
      //        ^^^^^
      //        explicit template argument
      

      【讨论】:

      • 这是正确的答案。我不知道他想做什么。
      猜你喜欢
      • 1970-01-01
      • 2019-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多