问题
I have a function of the following signature:
void foo(int argc, char const * const argv[]);
I would like to call it in a concise way, similar, but not necessary identical as below:
foo(3, {"one", "two", "three"});
I know that C supports compound literals just for this purpose (reference).
I also know how to solve the problem using templates (reference).
However, my problem is slightly different. The function signature is fixed - it normally takes arguments passed to main
and the size of the array is not predefined. I am writing tests for this function and in my case the passed arrays are known at compile-time.
Is there a way to call foo
without using temporary variables or wrapper functions like below?
char const * array[3] = {"one", "two", "three"};
foo(3, array);
template<int N>
void wrapper(char const * const (&array)[N])
{
foo(N, array);
}
回答1:
though I have no idea how compiler works, it works:
template<size_t N>
void foo(int argc, const char *(&&argv)[N]){
int i=0;
for( auto o: argv) {
++i;
cout<<"array"<<i<<" = " << o<<"\n";
}
cout<< "\narray size "<<i<<"\n"<<argc<<"\n";
return;
}
int main(){
foo(3, {"one", "two", "three"});
}
array1 = one
array2 = two
array3 = three
array size 3
3
回答2:
You can write a simple wrapper for arguments themselves.
Example (see below):
auto wrapper(std::initializer_list<const char*> lst) {
return lst.begin();
}
foo(3, wrapper({"one", "two", "three"}));
This solution requires that initializer_list
be destroyed when foo()
returns. The moment when it is destroy is implementation-defined:
It is implementation-defined whether the lifetime of a parameter ends when the function in which it is defined returns or at the end of the enclosing full-expression.
Thanks NathanOliver for pointing that out.
Edit. After the discussion that followed this question, it seems that the code above can easily be fixed by passing the initializer_list
by reference, not by value, i.e.:
auto wrapper(const std::initializer_list<const char*>& lst) {
return lst.begin();
}
foo(3, wrapper({"one", "two", "three"}));
Now the temporary initializer_list
is guaranteed to exist until foo()
returns:
Temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created.
Thanks cdhowie for clarifications.
来源:https://stackoverflow.com/questions/59811628/how-to-pass-a-temporary-array-to-a-function-in-standard-c17