Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 - declaring non-static data members as 'auto'

Does C++11 allow declaring non-static data members as 'auto' if they are initialized in the declaration? For example:

struct S {     auto x = 5;  // in place of 'int x = 5;', which is definitely allowed }; 

GCC 4.7 rejects the above code, while it accepts int x = 5;.

Assuming this is not a compiler bug but rather the standard really doesn't allow it, why not? It would be just as useful as declaring local variables auto.

like image 847
HighCommander4 Avatar asked Jul 03 '12 00:07

HighCommander4


People also ask

Can I initialize Non-static data member inside static block?

Yes... a non-static method can access any static variable without creating an instance of the class because the static variable belongs to the class.

What is non-static data member in C++ with example?

Non-static data members are the variables that are declared in a member specification of a class. And they have the example: class S { int& r; // non-static data member of reference type };

Can static members use non-static members give reasons?

In the static method, the method can only access only static data members and static methods of another class or same class but cannot access non-static methods and variables. Non-static method: Any method whose definition doesn't contain the static keyword is a non-static method.

What do you mean by declaring a data member static?

When a data member is declared as static , only one copy of the data is maintained for all objects of the class. Static data members are not part of objects of a given class type. As a result, the declaration of a static data member is not considered a definition.


1 Answers

The rule for prohibiting non-static members is in 7.1.6.4 clause 4:

The auto type-specifier can also be used in declaring a variable in the condition of a selection statement (6.4) or an iteration statement (6.5), in the type-specifier-seq in the new-type-id or type-id of a new-expression (5.3.4), in a for-range-declaration, and in declaring a static data member with a brace-or-equal-initializer that appears within the member-specification of a class definition (9.4.2).

I found the rationale for it being static here which reflects how James McNellis explains it in the comment.

One national body dislikes allowing the auto type-specifier for non-statics. From an e-mail to the authors:

    template< class T >     struct MyType : T {       auto data = func();       static const size_t erm = sizeof(data);     }; 

In order to determine the layout of X, we now have 2-phase name lookup and ADL. Note that func could be either a type or a function; it may be found in T, the namespace of MyType, the associated namespace(s) of T when instantiated, the global namespace, an anonymous namespace, or any namespaces subject to a using directive. With care we could probably throw some concept_map lookup in for luck. Depending on the order of header inclusion I might even get different results for ADL, and break the One Definition Rule - which is not required to be diagnosed.

Because of this controversy, the authors no longer propose that auto be allowed for non-static data members.

So, basically depending on the order of header inclusion, the type of data could be very different. Of course, auto x = 5; would not need to depend on 2-phase name lookup or ADL, however, I'm a assuming that they made it a "blanket" rule because otherwise, they would have to make individual rules for every use case which would make things very complicated.

In the same paper, the author proposes eliminating this restriction, however, it seems this proposal has been rejected probably due to the above rationale and also so that expected behavior can be the same no matter what the initializer is.

like image 53
Jesse Good Avatar answered Oct 22 '22 14:10

Jesse Good