How to pass a temporary array to a function in standard C++17

*爱你&永不变心* 提交于 2020-06-18 01:27:29

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!