views:

501

answers:

5

Basically I'd like to do something like that:

int[3] array_func()
{
    return {1,1,1};
}

int main(int argc,char * argv[])
{
    int[3] point=array_func();
}

But that doesn't seem legal in C++. I know I can use vectors, but since I know the size of the array is a constant, it seems like a loss of performance is likely to occur. I'd also like to avoid a new if I can, because allocating stuff on the stack is easier and also likely to improve performance.

What's the solution here?

+4  A: 

You can wrap it in a struct, to make it returnable by value:

struct Vec3
{
  float x[3];
}

Vec3 array_func()
{
  Vec3 x = { 1.f, 1.f, 1.f };

  return x;
}

I don't think you can use the array initializer syntax directly in the return statement. Of course you could introduce a constructor (structs are just classes with all members public, after all):

struct Vec3
{
  Vec3(a, b, c)
  {
    x[0] = a;
    x[1] = b;
    x[2] = c;
  }

  float x[3];
}

Vec3 array_func()
{
  return Vec3(1.f, 1.f, 1.f);
}
unwind
That would be the best answer except that such a struct already exists: http://stackoverflow.com/questions/1755000/1755017#1755017
sbi
I chose it as the best answer because it answers my question, plain and simple, without pushing a library I didn't ask for. Not that litb's answer is bad, I just found unwind's answer a bit clearer.
static_rtti
"...pushing a library I didn't ask for..." Well, we're talking _boost_ here, not just some library. Anyway, there's a very good chance your standard lib implementation comes with `std::tr1::array` (C++03 or TR1) or even `std::array` (C++1x), which is exactly the same. (Which goes to show that boost isn't just another library. It's a testbed for the next C++ standard, founded by std committee members for exactly that reason, has _very_ high quality standards and demanding reviews, and it's contributing a whole lot of stuff to the next standard library.)
sbi
+11  A: 

Put the array into a struct. boost::array is such a package:

boost::array<int, 3> array_func() {
  boost::array<int, 3> a = {{ 1, 1, 1 }};
  return a;
}

int main() {
  boost::array<int, 3> b = array_func();
}

Quick and dirty:

template<typename E, size_t S>
struct my_array {
  E data[S];
};

Notice how you can use aggregate initialization syntax.

Johannes Schaub - litb
+2  A: 

you can't return a fixed size array in C++. you may return a pointer to int (which would be used as an array) but that would require allocating the array on the heap using new.

anyway, you can pass your array as an argument to your function:

void array_func( int result[3])
{
    result[0] = 1;
    result[1] = 1;
    result[2] = 1;
}

int main(int argc,char * argv[])
{
    int point[3];
    array_func( point );
}

however, this looks more like C than C++...

Adrien Plisson
new isn't needed necessarily. It's also possible to make the array static inside the array_func function (if that's possible depends of course)
Christian
Um, isn't that `3` in the parameter declaration ignored?
sbi
yes you are right, finally, i am not even sure it compiles. you may have to omit the array size in the declaration of the function...
Adrien Plisson
@Adrien: It will compile, but the compiler will ignore the number 3, silently "decaying" the type of result from `int result[3]` to `int *result` (usually without even giving a warning). Which is a bit sneaky of the compiler if you ask me ;)
j_random_hacker
...and would also open the door to a buffer overflow, but that's how C works. anyway, when used on purpose, this solution still works.
Adrien Plisson
+2  A: 

Using C++0x, the almost finalized new C++ standard (already implemented in latest gcc and msvc IIRC), you can do it exactly as you want! Simply use std::array instead of int[3].

std::array<int, 3> array_func()
{
    return {1,1,1};
}

int main(int argc,char * argv[])
{
    std::array<int, 3> point = array_func();
}
Didier Trosset
+1  A: 

boost::array is a wrapper for a stack-based array.

Note that stack allocation is only going to stay cheaper than using 'new' when you're not having to copy large arrays around.

Kylotan