As you probably know 'C++' doesn't allow either passing or returning arrays by value (don't mislead yourself that declaring array parameters will give you that functionality, every parameter declared as array will be 'adjusted' to a pointer to it's first element - which is some kind of odd, but 'C++' holds big legacy). You can use "std::array" for the case but as it have some non-inline methods it will require external linkage and slow-down your program. My wrapper on the other hand is fully inline and will be expanded all in compile-time so heavy optimizations can be performed. As I said it allow passing native arrays and returning them by value. It also allow assigning arrays and some-time in the future I could add addition of them too. The wrapper also allow creation of unnamed and uninitialized temporaries. The wrapper:
template<typename type>
struct ugaw //uninitialized temporary generator and array wrapper
{
ugaw() {}
ugaw(const ugaw&) = default;
ugaw(const type & arg) { *this = *(const ugaw*)arg; } //data-only copy constructor (doesn't invoke any 'type' functions)
& operator type() & {return d;} //cast operator for a reference to 'type' (used for arrays)
& operator const type() const & {return d;} //cast operator for a const reference to 'type' (used for arrays)
ugaw & operator =(const ugaw&) = default;
ugaw & operator =(const type &arg) { *this = *(const ugaw*)arg; } //data-only assignment operator
type *operator & () & { return &d; } //address operator to return the actual data stored
const type *operator & () const & { return &d; } //and a constant version
type d;
};
And some uses:
ugaw<int [4]> FuncAdd(ugaw<int [4]> arg_0, const ugaw<int [4]> arg_1)
{
for(size_t i(0); i < sizeof(arg_0) / sizeof(arg_0[0]); ++i)
arg_0[i] += arg_1[i];
return arg_0;
}
int main()
{
int var[4]{0, 1, 2, 3};
int var1[4]{1, 1, 2, 3};
auto &&refArray = FuncAdd(var, var1);
for(size_t i(0); i < sizeof(var) / sizeof(var[0]); ++i)
cout << var[i] << endl;
cout << "Here" << endl;
for(size_t i(0); i < sizeof(var1) / sizeof(var1[0]); ++i)
cout << var1[i] << endl;
cout << "Here" << endl;
for(size_t i(0); i < sizeof(refArray) / sizeof(refArray[0]); ++i)
cout << refArray[i] << endl;
return 0;
}
Life example.
It also have another, more complex usage - declaring unnamed and uninitialized temporaries. This is when you don't care for the output of some function. Example you have:
void FuncDoSomethingAndStoreResult(int (&refArrayOutput)[260]);
This function will do something and store some output in 'refArrayOutput', but sometimes you wouldn't care for it and you'll only want the function to do something for you. For now this was only possible by using default 'zero-initialization', which however is a performance waste. With my wraper you can do that without the performance waste by using default parameter:
void FuncDoSomethingAndStoreResult(int (&refArrayOutput)[260] = const_cast<int (&)[260]>((const int (&)[260])ugaw<int [260]>().d));
So now if you care about the output you will instance the function with a variable name where it will be stored, otherwise you will no pass any arguments.
Examples:
int var2[260];
FuncDoSomethingAndStoreResult(var2); //store output in 'var2'
FuncDoSomethingAndStoreResult(); //store nothing