为什么编译时获取类成员变量地址会导致C2327和C2065?

问题描述 投票:0回答:1

我有以下代码块,它在一个简单的、新创建的 hello world VS2017 项目中“工作”,在我们拥有的另一个应用程序中,但由于某种原因我无法识别,当我将其移植到我当前正在开发的应用程序。

/**
 * This can be used to associate a class variable to a type and a string in order to load it easily from XML
 * or JSON.
 */
template<typename Class, typename T>
struct Property {
  constexpr Property( T Class::*aMember, const char* aName )
    : member { aMember }, name { aName } {}

  using Type = T;
  using ClassType = Class;

  T Class::*member;
  const char* name;
};

struct MajorPaine
{
  int mInt;

  // All errors are "spammed" by the following line:
  static constexpr auto perp = Property<MajorPaine, decltype(MajorPaine::mInt)>{ &MajorPaine::mInt, "int" };
};

当我编译此代码时,出现这些错误(使用适用于 x86 的 Microsoft (R) C/C++ 优化编译器版本 19.16.27034 编译):

error C2327: 'MajorPaine::mInt': is not a type name, static, or enumerator
error C2065: 'mInt': undeclared identifier
fatal error C1903: unable to recover from previous error(s); stopping compilation

错误的原因可能是什么?

c++ visual-studio-2017
1个回答
0
投票

回答我自己的问题,以帮助人们避免在这个(以及未来的我)上花费时间。


tldr:未设置编译器标志

\permissive-
。设置它确实修复了它。

根据 /permissive- 标志的 帮助页面

[...] 编译器还实现了更多两阶段名称查找的要求。当设置 /permissive- 选项时,编译器会解析函数和类模板定义,并识别模板中使用的依赖名称和非依赖名称。 [...]

因此,我认为这两个错误都源于编译器在读取结构时执行了一次传递,并且不知道mInt确实存在。允许编译器执行两个阶段可以让它看到成员并实际使用它。

    

© www.soinside.com 2019 - 2024. All rights reserved.