首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内联成员初始化器,包含指向成员的指针

内联成员初始化器,包含指向成员的指针
EN

Stack Overflow用户
提问于 2015-04-01 13:34:43
回答 1查看 191关注 0票数 7

在工作中,我正在做一些实验,以便在代码库中引入一些反思。基本上,我想要实现的是在数据成员的初始化器类型中捕获指向数据成员的指针:

代码语言:javascript
复制
template<class Class, int Class::*dataMember>
struct Reflect
{
  operator int() {return 0;}
};

class Foo
{
public:
  int bar = Reflect<Foo, &Foo::bar>{};
};

虽然clang3.4.1 (http://gcc.godbolt.org/)和Intel C++ XE14.0能够编译这段代码,但当使用MSVC12时,我得到以下错误消息:

错误C2065:“bar”:未声明的标识符 错误C2975:'dataMember‘:“反射”的无效模板参数,预期编译时常量表达式

此外,gcc 4.9.2似乎也有问题:http://ideone.com/ZUVOMO

所以我的问题是:

  1. 上面的代码是否有效的C++11?
  2. 如果是的话,对失败的编译器有什么解决办法吗?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-01 14:02:33

VC++抱怨的当然不是问题;basic.cope. about /1,6:

名称的声明点是在名称的完整声明符(第8条)之后,在其初始化器(如果有的话)之前,除非如下所示.…在类成员声明点之后,可以在其类.的范围中查找成员名称。

这意味着名称查找是好的。然而,正如@hvd在注释中所指出的,这种结构的语法中存在一定的歧义。

GCC大概会在逗号之前解析上面的一行:

代码语言:javascript
复制
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.

一旦遇到其他人就会逃跑。

让GCC高兴的解决办法是

代码语言:javascript
复制
    int bar = decltype( Reflect<Foo, &Foo::bar>{} )();

Demo。但是,这对VC++没有帮助,因为它显然混淆了错误消息所指示的声明点。因此,将初始化程序移动到构造函数中将有效:

代码语言:javascript
复制
int bar;

Foo() : bar( Reflect<Foo, &Foo::bar>{} ) {}
// (also works for GCC)

..。虽然在声明bar时提供了初始化程序,但不能。rextester上的Demo #2

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29392234

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档