3

Why does this compile in VS 2013

int main()
{

    int a[3] = { 1, 2, 3 };

    return 0;

}

but this gives the error

class TestClass
{

    int a[3] = { 1, 2, 3 };

};

How do I fix it?

huysentruitw
  • 27,376
  • 9
  • 90
  • 133
abalter
  • 9,663
  • 17
  • 90
  • 145
  • What error does it give? – Scott Hunter Jan 11 '15 at 01:08
  • AFAIK this is a C++11 feature that Microsoft hadn't implemented at the time of VS2013's release. It compiles with [g++](http://coliru.stacked-crooked.com/a/744a928564817d8f) and [clang++](http://coliru.stacked-crooked.com/a/46cb648754583e84). – Borgleader Jan 11 '15 at 01:08
  • @ScottHunter "cannot specify explicit initializer for arrays". – abalter Jan 11 '15 at 01:09
  • @Borgleader Why does the first example compile and not the second? What is the workaround? – abalter Jan 11 '15 at 01:15
  • @abalter Because the former has been in the language since "forever" whereas the latter is a newer feature that's not been implemented yet (in VS). For the workaround see Cheers' answer. – Borgleader Jan 11 '15 at 01:18
  • @Borgleader So the difference is initializing in class scope vs in a method? – abalter Jan 11 '15 at 01:28
  • @abalter yep pretty much. I added a link with more info on this feature in my answer, if you're interested in reading more about it. – Borgleader Jan 11 '15 at 01:55
  • Possible duplicate of [cannot specify explicit initializer for arrays](http://stackoverflow.com/questions/20894398/cannot-specify-explicit-initializer-for-arrays) – waldyrious Jan 02 '16 at 16:37

3 Answers3

9

From Bjarne's C++11 FAQ page:

In C++98, only static const members of integral types can be initialized in-class, and the initializer has to be a constant expression. [...] The basic idea for C++11 is to allow a non-static data member to be initialized where it is declared (in its class).

The problem is, VS2013 doesn't implement all the features of C++11, and this is one of them. So what I suggest you use is std::array (take note of the extra set of braces):

#include <array>

class A
{
public:
    A() : a({ { 1, 2, 3 } }) {} // This is aggregate initialization, see main() for another example

private:
    std::array<int, 3> a; // This could also be std::vector<int> depending on what you need.
};

int main()
{
    std::array<int, 3> std_ar2 { {1,2,3} };
    A a;

    return 0;
}

cppreference link on aggregate initialization

If you're interested you can click on this link to see that what you did does compile when using a compiler that has implemented this feature (in this case g++, I've tried it on clang++ and it works too).

Borgleader
  • 15,826
  • 5
  • 46
  • 62
1

Why: not yet implemented in that version of Visual C++.

Fix: use std::array and initialize in each constructor.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
0

In alternative to using std::array as the other answers suggest, you can use the approach described in this answer: mark the array as static in the class declaration (which would usually be in the header file), and initialize it in the source file. Like so:

test.h:

class TestClass
{
    static int a[3];
};

test.cpp:

int TestClass::a[3] = { 1, 2, 3 };

Eventually, this should become unecessary as MSVC catches up to C++11.

waldyrious
  • 3,683
  • 4
  • 33
  • 41