C++ 包含指向成员的指针的内联成员初始值设定项

C++ 包含指向成员的指针的内联成员初始值设定项,c++,templates,c++11,initializer,pointer-to-member,C++,Templates,C++11,Initializer,Pointer To Member,在工作中,我正在做一些实验,以便在我们的代码库中引入一些反射。基本上,我想要实现的是在数据成员的初始值设定项的类型内捕获一个指向数据成员的指针: 模板 结构反射 { 运算符int(){return 0;} }; 福班 { 公众: int bar=Reflect{}; }; 虽然CLAN3.4.1()和英特尔C++ XE 14能够编译这段代码,但是当使用MSVC12时,我得到以下错误信息: 错误C2065:“条”:未声明的标识符 错误C2975:'dataMember':对于'Reflect'的

在工作中,我正在做一些实验,以便在我们的代码库中引入一些反射。基本上,我想要实现的是在数据成员的初始值设定项的类型内捕获一个指向数据成员的指针:

模板
结构反射
{
运算符int(){return 0;}
};
福班
{
公众:
int bar=Reflect{};
};

虽然CLAN3.4.1()和英特尔C++ XE 14能够编译这段代码,但是当使用MSVC12时,我得到以下错误信息:

错误C2065:“条”:未声明的标识符

错误C2975:'dataMember':对于'Reflect'的模板参数无效,应为编译时常量表达式

此外,gcc 4.9.2似乎也有问题:

所以我的问题是:

  • 上面的代码是有效的C++11吗
  • 如果是,对于失败的编译器有什么解决办法吗

  • VC++所抱怨的当然不是问题;[基本范围pdecl]/1,6:

    名称的声明点在其完成后立即出现 声明人(第8条)及其初始值设定人之前(如有),除非 如下所示。[…]

    在类成员的声明点之后,可以 在其类的范围内查找。

    这意味着名称查找没有问题。然而,正如@hvd在评论中指出的,这些结构的语法中存在某些歧义。
    大概GCC会解析上述行,直到逗号:

    int bar = Reflect<Foo,
    // at this point Reflect < Foo can be a perfectly fine relational-expression.
    // stuff after the comma could be a declarator for a second member.
    

    int bar=reflect是一个尚未解决的语言问题,IIRC。不清楚逗号何时分隔模板参数,何时分隔两个成员<代码>整数a=b::f
    可以声明成员
    a
    并将其初始化为
    b::f
    ,也可以声明成员
    a
    初始化为
    b::f
    。NSDMIs可能指的是类中尚未声明的成员,这一事实使问题变得复杂。@hvd我认为语法明确地涵盖了这一点。说得好。您能找到与此相关的DR吗?对于与函数的默认参数非常相关的问题,有。也许这就是我记得的,也许NSDMIs没有单独的问题。@hvd我很确定
    d=e
    不能是有效的模板参数。然而,这是从解析器开始的语法问题,不是吗?`重载赋值运算符可以声明为
    constexpr
    ,因此赋值可以发生在模板参数内。
        int bar = decltype( Reflect<Foo, &Foo::bar>{} )();
    
    int bar;
    
    Foo() : bar( Reflect<Foo, &Foo::bar>{} ) {}
    // (also works for GCC)