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:

  1. is above piece of code valid c++11?
  2. 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

Popular posts from this blog

tcpdump - How to check if server received packet (acknowledged) -