c++ - Inline member initializer containing pointer to member -
at work, i'm experimenting bit bring reflection our codebase. want achieve, capture pointer data-member inside type of data-member's initializer:
template<class class, int class::*datamember> struct reflect { operator int() {return 0;} }; class foo { public: int bar = reflect<foo, &foo::bar>{}; };
although clang 3.4.1 (http://gcc.godbolt.org/) , intel c++ xe 14.0 able compile piece of code, when using msvc12 following error message:
error c2065: 'bar' : undeclared identifier
error c2975: 'datamember' : invalid template argument 'reflect', expected compile-time constant expression
furthermore, gcc 4.9.2 seems have trouble it: http://ideone.com/zuvomo.
so questions are:
- is above piece of code valid c++11?
- if yes, there work arounds failing compilers?
what vc++ complains not problem; [basic.scope.pdecl]/1,6:
the point of declaration name after complete declarator (clause 8) and before initializer (if any), except noted below.[…]
after point of declaration of class member, member name can looked in scope of class.
this implies name lookup fine. however, pointed out @hvd in comments, there ambiguities in grammar of such constructs.
presumably gcc parses above line until comma:
int bar = reflect<foo, // @ point reflect < foo can fine relational-expression. // stuff after comma declarator second member.
and bails out once rest encountered.
workaround makes gcc happy is
int bar = decltype( reflect<foo, &foo::bar>{} )();
demo. not vc++ though, apparently confuses point of declaration indicated error message. moving initializer constructor work:
int bar; foo() : bar( reflect<foo, &foo::bar>{} ) {} // (also works gcc)
... while providing initializer @ declaration of bar
cannot. demo #2 on rextester.
Comments
Post a Comment