Passing a std::array of unknown size to a function
Is there a simple way to make this work, as one would with plain C-style arrays?
No. You really cannot do that unless you make your function a function template (or use another sort of container, like an std::vector
, as suggested in the comments to the question):
template<std::size_t SIZE>
void mulArray(std::array<int, SIZE>& arr, const int multiplier) {
for(auto& e : arr) {
e *= multiplier;
}
}
Here is a live example.
How to pass an std::array with unknown size? in C++
If you know the array size in compile-time, as is implied by your usage of std::array
, then you have templates to the rescue. To restrictively support std::array
s of int
of different sizes you can do this:
#include <array>
template <size_t N>
void ArrayFunc(std::array<int, N> arr)
{
// Do something with `arr`
}
int main()
{
std::array<int, 10> arr10;
std::array<int, 20> arr20;
ArrayFunc(arr10);
ArrayFunc(arr20);
return 0;
}
Note the passing by value of the arr
parameter of ArrayFunc()
, a thing you should consider whether it is desired or not -- I was just following your example (in pseudo) in your question. If you don't really want to copy the entire std::array
for each function call then you can do either:
template <size_t N>
void ArrayFunc(std::array<int, N>& arr)
or
template <size_t N>
void ArrayFunc(const std::array<int, N>& arr)
Depending on whether you will be modifying arr
in the function or not.
Passing unknown size std::Array in a function with template. How can I correct this code?
I wrote this code using 2d Vector and Array.
That is appropriate, as you do not know the size of the matrix until run time.
But I wanted to use
std::array
this time [...]
Well, that's a problem because the size of a std::array
must be known at compile time. Moving away from C-style arrays is a recommended move, but you have to know where to go. Use the correct tool for the job at hand.
Fixed-size arrays: For arrays whose size is known by the compiler, a std::array
is a reasonable replacement. In fact, the std::array
is probably nothing more than the C-style array with a different interface.
Variable-size arrays: For arrays whose size is not known until run time, a std::vector
is a reasonable replacement. Even though the name does not say "array", it is an array. It is a bit more complex than std::array
, but that is because it supports sizes not known at compile time.
This distinction tends to be better-known by those not using gcc, as that compiler has an extension that supports declaring variable-size C-style arrays using the same syntax as declaring fixed-size C-style arrays. It is standard C++ to declare an array along the lines of int col[10]
. However, it is not standard C++ to declare an array along the lines of int col[sizeY]
, where sizeY
has a value supplied at run time. The latter syntax is supported by gcc as an extension, and some people use it without realizing it is an extension (ported from gcc's C support). To some extent, std::vector
makes this extension available in a more portable form.
Passing a std::array of unknown type and size to a constructor of a templated function
As state in comment, in C++17 it's valid to use:
std::array<uint16_t, 100> buffer;
Pipeline pipeline(buffer); // Pipeline<uint16_t, 100>
Earlier than C++17 you need to use a helper function:
template <typename T, std::size_t N>
Pipeline<T, N> make_pipeline(std::array<T, N>& buffer)
{
return Pipeline<T, N>(buffer);
}
auto pipeline = make_pipeline(buffer); // Pipeline<uint16_t, 100>
That assumes that your class is move (or copy) constructable.
Passing and Returning a 2D array of unknown size in C++
The problem is that the return type of your function is int**
but you are returning array2d
which decays to a double (*)[3]
due to type decay. Thus, there is a mismatch in the specified return type of the function and the type you're actually returning.
To solve this you can either use std::vector
or use the placeholder type auto
as shown below:
template<typename Value_t, size_t FirstDim, size_t SecondDim>
//auto used here
auto FooTakes2D_ArrayRef_to_Print(Value_t (&array2d)[FirstDim][SecondDim]) -> decltype(array2d)
{
for(size_t i=0; i<FirstDim; ++i)
{
for(size_t j=0; j<SecondDim; ++j)
{
std::cout<<array2d[i][j]<<' ';
}
std::cout<<"\n";
}
return array2d;
}
int main()
{
double arr_d[][3]= { {1,2,3}, {4,5,6} };
//auto used here
auto arr=FooTakes2D_ArrayRef_to_Print(arr_d);
}
Working demo
Passing array with unknown size to function
In C++ language, multidimensional array declarations must always include all sizes except possibly the first one. So, what you are trying to do is not possible. You cannot declare a parameter of built-in multidimensional array type without explicitly specifying the sizes.
If you need to pass a run-time sized multidimensional array to a function, you can forget about using built-in multidimensional array type. One possible workaround here is to use a "simulated" multidimensional array (1D array of pointers to other 1D arrays; or a plain 1D array that simulates multidimensional array through index recalculation).
std::array with unknown length as a type for template function specification
What about something like
template <typename T>
void foo (T const &)
{ std::cout << "foo generic" << std::endl; }
template <std::size_t Dim>
void foo (std::array<float, Dim> const &)
{ std::cout << "foo float array dim " << Dim << std::endl; }
?
The following is a full working example
#include <array>
#include <iostream>
template <typename T>
void foo (T const &)
{ std::cout << "foo generic" << std::endl; }
template <std::size_t Dim>
void foo (std::array<float, Dim> const &)
{ std::cout << "foo floar array dim " << Dim << std::endl; }
int main ()
{
foo(0);
foo(std::array<float, 12U>{});
}
Related Topics
What Is the Easiest Way to Parse an Ini File in C++
The Simplest and Neatest C++11 Scopeguard
What Default Promotions of Types Are There in the Variadic Arguments List
Start Windows Service from Application Without Admin Right(C++)
How to Render an Opengl Frame in C++ Builder
Linking Fortran and C++ Binaries Using Gcc
Selecting a Member Function Using Different Enable_If Conditions
Checking for Null Pointer in C/C++
Unnecessary Curly Braces in C++
What Does Template <Unsigned Int N> Mean
How to Switch Between Blas Libraries Without Recompiling Program