我有以下代码块,它在一个简单的、新创建的 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
错误的原因可能是什么?
回答我自己的问题,以帮助人们避免在这个(以及未来的我)上花费时间。
tldr:未设置编译器标志
\permissive-
。设置它确实修复了它。
根据 /permissive- 标志的 帮助页面,
[...] 编译器还实现了更多两阶段名称查找的要求。当设置 /permissive- 选项时,编译器会解析函数和类模板定义,并识别模板中使用的依赖名称和非依赖名称。 [...]
因此,我认为这两个错误都源于编译器在读取结构时执行了一次传递,并且不知道mInt
确实存在。允许编译器执行两个阶段可以让它看到成员并实际使用它。