views:

179

answers:

3

suppose we have following function:

void someFunction(int * araye){
 for (int i=0;i<5;i++)
  cout <<araye[i]<<' ';
 cout <<'\n';
}

can we pass an array to this function by following syntax, under upcoming c++0x standards? :

someFunction({1,2,3,4,5});

if that's true, will we even be able to use this syntax in any case in which, array elements are from POD types like below :

class Test{
 int adad1;
 int adad2;
};
void someFunction(Test * araye){
 for (int i=0;i<3;i++)
  cout <<araye[i].adad1<<'-'<<araye[i].adad2<<' ';
 cout <<'\n';
}
someFunction({{1,2},{3,4},{5,6}});

Edit->after what people said:
So you guys are telling that the expression between braces will be basically treated as an initializer_list and are proposing using an extra function that pulls a pointer out of that initializer_list and passes it to the intended function, but this method seems to me like a hack to be able to use my intended function with that expression as an argument, with that said I think I shouldn't use that expression as an argument at all, when my intended function parameter is a single pointer, or there might be another approach to use that expression? .

+2  A: 

Wikipedia would seem to suggest that you can do this but only by declaring the function to take a std::initializer_list<int> as an argument.

David
yeah but that's different from a single pointer.
Pooria
@Pooria: Depending on implementation, it may or may not be. An implementation is free to treat `initializer_list<T>` basically however it pleases, within the confines of standards compliance. It might just be an array in the static data area, and the `begin()` method might just return a `const T*`.
Jon Purdy
@Jon: according to the C++0x draft standard, `begin()` *does* just return a `const T*`.
Mike Seymour
@Mike: Well, there you go. See comment on @Cubbi's answer.
Jon Purdy
+4  A: 

The type of the expression {1,2,3,4,5} is std::initializer_list<int>. It's an object which has member functions size(), begin(), end(), but no operator[] (per 18.9/1 of the C++0x FCD)

If your function took std::vector or any other standard container, this would work because containers can be constructed from initializer_lists (they all provide non-explicit constructors that take them):

void someFunction(std::vector<int> araye)
{
         for (int i=0;i<5;i++)
                   std::cout << araye[i] <<' ';
         std::cout <<'\n';
}
int main()
{
        someFunction({1,2,3,4,5});
}

If you want to have a function that takes a pointer, you will need to somehow manually convert an initializer_list into something that you can access in such manner:

void someFunction(int* araye)
{
         for (int i=0;i<5;i++)
                   std::cout << araye[i] <<' ';
         std::cout <<'\n';
}
void someFunction(std::vector<int> v)
{
        someFunction(&v[0]);
}
int main()
{
        someFunction({1,2,3,4,5});
}
Cubbi
It could be more efficient if you `move` the `initializer_list`.
Jon Purdy
@Jon: Can you expand on this?
sbi
@sbi: Never mind, see comments on @David's answer. You can just write `someFunction(std::initializer_list<int> v) { someFunction(v.begin()); }` instead, which avoids copying the `initializer_list` into the `vector`.
Jon Purdy
@Jon Purdy: Good point. I tried it initially, but without `const` it did not compile and I didn't give it a thought.
Cubbi
+3  A: 

If your function takes const int*, rather than int*, then you just need a small trampoline function to pull the pointer out of the std::initializer_list<int> that the brace initialiser produces. Something like this (probably; I don't have a C++0x compiler to test with)

void someFunction(const int * array){
    for (int i=0; i<5; i++)
        std::cout << array[i] << ' ';
    std::cout << '\n';
}

void someFunction(const std::initializer_list<int>& init) {
    someFunction(init.begin());
}

someFunction({1,2,3,4,5});

If your function needs to know the end or size of the array (which will usually be the case), then pass either init.end() or init.size() as a second argument.

Mike Seymour
Compiles and runs as expected with g++ 4.4.4, after changing `initializer` to `initializer_list`
Cubbi
@Cubbi: oh yes. Fixed it.
Mike Seymour