如何将类型数组的动态对象传递给函数?

时间:2018-12-03 22:07:42

标签: c++ arrays

我想将动态大小标准和类型名类型数组传递给函数。

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

我尝试的代码:

#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的预期编译时常量表达式。 我的函数头也不是很漂亮。但是我想不办法在不传递通用指针或创建大小为属性的类数组模板的情况下实现动态大小。

2 个答案:

答案 0 :(得分:7)

根本没有理由在此处使用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 <<。您还可以将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;
}

答案 1 :(得分:6)

如果您希望功能模板的类型是模板参数,而大小是运行时属性(如果要避免二进制膨胀,这很有意义),那么您需要这样的东西:

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 template 参数,而不是功能参数。还要注意,我们永远不会为参数指定参数:这是因为参数是推导的。如果确实要像在示例中那样传递空指针,则将无法从函数调用中推断出模板参数,而必须显式指定它:

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