今月にビルドされたgcc4.7で対応していることを確認。
struct S { int member = 123 ; S() = default ; S( int value ) : member(value) { } } ; int main() { S s1 ; // s.member == 123 S s2(456) ; // s.member == 456 }
なお、非staticデータメンバーの宣言にauto specifierを使うことはできない。これは、auto specifierが、ブロック、名前空間スコープ、for文の初期化句にしか使われてはならないとされているためである。
struct S { auto member = 0 ; // error } ;
ちなみに言っておくと、staticデータメンバーにはauto specifierを使うことができる。これは、staticデータメンバーが、実は名前空間スコープであるからだ。staticデータメンバーは、クラス定義の中に書かなければならないとか、クラス名による修飾をしなければならないなどの制約はあるが、名前空間スコープに属する名前である。
struct S { static auto const member = 0 ; // OK, type is determined to be "const int" } ;
もちろん、staticデータメンバーに初期化子が許されているのは、constなリテラル型だけであるので、autoがそれ以外の型に推定された場合は、エラーとなる。
struct S { static auto member = 0 ; // Error, the type of static member is not const literal type. } ;
ちなみに、gccには七ヶ月前、上記のコードを通してしまうバグがあったが、バグレポートを送ったところ、現在では修正されている。
> auto specifierが、ブロック、名前空間スコープ、for文の初期化句にしか使われてはならないとされている
ReplyDelete...
> これは、staticデータメンバーが、実は名前空間スコープであるからだ。
7.1.6.4 p4 の "The auto type-specifier can also be used in declaring a variable in ..." を見落とされているようです。同 7.1.6.4 の p3 に挙げられている上記3つ以外に、初期化子付き static データメンバの宣言を含めていろいろと auto が使える場所が挙げられています。それでもやっぱり non-static データメンバは含まれませんが。