4

Now I have a function in C++

void F( std::array<int,3> x )
{
    //...
}

I hope the argument 'x' could have a default value, how can I do this?

If not a function argument, I can simply use

std::array<int,3> x = {1,2,3};

But for a function argument, the code

void F( std::array<int,3> x = {1,2,3} )
{
    //...
}

will make compiler error.


I test in MSVC 2012, and got error C2143, C2059, C2447. And also error in g++ 4.6.3


Is there any way make it has a default value?

thanks.

10
  • What compiler error? Which compiler? (It might be a bug.. clang3.2 accepts your code; and I think your example complies to the Standard - it's aggregate-initialization) Commented May 2, 2013 at 11:20
  • I had add the comiple error. It looks that is my compiler not support this syntax yet... Commented May 2, 2013 at 11:36
  • 1
    I found a stupid workaround...Use lambda expression. void F( std::array<int,3> x = [](){std::array<int,3> x = {1,2,3}; return x; }() ){} This works both on MSVC11 and G++ 4.6.3. Commented May 2, 2013 at 12:24
  • It looks like this was not implemented yet in gcc 4.6.3, see this SO question. Consider looking at Microsoft Connect and file a bug report if it hasn't been detected yet. AFAIK, Morwenn's answer is wrong and this should be possible according to the Standard. Commented May 2, 2013 at 12:38
  • @DyP After reading again the standard, I think my answer is indeed wrong: he should be able to initialize the array the way he does. However, the work-around is not wrong: the standard says that braces can be elided, not that they have to. Commented May 2, 2013 at 13:40

1 Answer 1

11

Your solution should work according to the standard, but is not implemented in some compilers. Most of them can initialize instances of std::array with the syntax x = {{1,2,3}}, not with x = {1, 2, 3}. If you want it to work as of today, your function should be:

void F( std::array<int,3> x = {{1,2,3}} )
{
    //...
}

This is because std::array just has a C array underneath and initialize it with aggregate initialization. The first pair of braces are for the list initialization list while the second pair of braces is for the C-array initialization.

According to the standard (8.5.1.11), the outer braces can be elided in such a case if (and only if) you use the sign = for initialization. However, some compilers still do not support this behaviour (g++ being one of them).

And as a bonus, you can check it online with ideone.

Sign up to request clarification or add additional context in comments.

12 Comments

Note that the standard is not totally clear about the implementation having an array data member, which can lead to confusion.
I'm not entirely sure about this. The Standard says in [array.overview]/2 that an array is an aggregate that can be initialized like std::array<int,3> a = {1,2,3};. There have to be two braces for direct-init, std::array<int,3> a{{1,2,3}};
@Morwenn Thanks for your answer, but the code still get compile error in MSVC 2012.
@Heresy Initializer-lists are not supported in MSVC 2012, see SO question, MSDN reference
@Heresy Maybe with the November 2012 CTP version
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.