3
#include <iostream>
using namespace std;

struct test
{
   int factorX;
   double coefficient;
};

int main()
{
   test firstTest = {1, 7.5}; //that's ok

   test *secondTest = new test;
   *secondTest = {8, 55.2}; // issue a compiler warning

}

I don't understand why the compiler issues the following warning:

test2.cpp:13:33: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
test2.cpp:13:33: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]

I know that in C++11 I can omit the assignment operator but that's not the case. I am using g++ 4.7.2.

Toshko
  • 33
  • 4

3 Answers3

5

Your test structure is an aggregate. While initialization of an aggregate with the braces syntax is supported in C++98, assignment is not.

Here, what is really going on is that the compiler invokes the implicitly generated move-assignment operator, which takes a test&& as its input. In order to make this call legal, the compiler will have to convert {8, 55.2} into an instance of test by constructing a temporary from it, then move-assign *secondTest from this temporary.

This behavior is supported only in C++11, which is why the compiler is telling you that you have to compile with the -std=c++11 option.

Community
  • 1
  • 1
Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
2

Since first is initialization and second is assignment. You can initialize simple struct this way in C++98, but not assign.

8.5.1/1

An aggregate is an array or a class (clause 9) with no user-declared constructors (12.1), no private or pro- tected non-static data members (clause 11), no base classes (clause 10), and no virtual functions (10.3).

8.5.1/2

When an aggregate is initialized the initializer can contain an initializer-clause consisting of a brace- enclosed, comma-separated list of initializer-clauses for the members of the aggregate, written in increasing subscript or member order.

But second construction calls operator = of class, since you have no user-defined copy c-tor, default copy c-tor will be called, in C++11 with expression in {} can be constructed object of needed type, but not in C++98.

ForEveR
  • 55,233
  • 2
  • 119
  • 133
1

The error message is telling you what you need to do, you need to add -std=c++11 or -std=gnu++11 to the command line when compiling your program. It is a C++11 feature and you have to enable it:

 test2.cpp:13:33: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
                                                                           ^^^^^^^^^     ^^^^^^^^^^^

As Andy was saying it is a C++11 feature to use an implicitly generated move function on the temporary which is created from {8, 55.2}, which is what you have in the second case.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • Yeah, I know this. But what's the difference between the two initializations? Without "secondTest", the compiler don't ask me to use the -std=c++11 flag and I can't understand why. – Toshko Mar 20 '13 at 12:59
  • 1
    @Toshko: The difference is that the second one is not an initialization: it is an assignment – Andy Prowl Mar 20 '13 at 13:02