Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 指向作为静态成员的成员变量的指针_C++_Cmake_C++17_Visual Studio 2019 - Fatal编程技术网

C++ 指向作为静态成员的成员变量的指针

C++ 指向作为静态成员的成员变量的指针,c++,cmake,c++17,visual-studio-2019,C++,Cmake,C++17,Visual Studio 2019,这些天来,我在忙于一个项目研究,寻找一种适合我需要的反映数据模型。 当我使用最新稳定版本的g++进行第一次学习时,我在VisualStudio19中失败了。太糟糕了,因为后者是我的主要平台 实际上,我尝试将指向成员变量的指针存储到另一个静态成员变量中。因此,对我来说,内联做这件事是非常可取的(以适应我更大的概念) 我将失败的细节缩减为以下MCVE: struct Field { }; struct Class { template <typename CLASS>

这些天来,我在忙于一个项目研究,寻找一种适合我需要的反映数据模型。 当我使用最新稳定版本的g++进行第一次学习时,我在VisualStudio19中失败了。太糟糕了,因为后者是我的主要平台

实际上,我尝试将指向成员变量的指针存储到另一个静态成员变量中。因此,对我来说,内联做这件事是非常可取的(以适应我更大的概念)

我将失败的细节缩减为以下MCVE:

struct Field { };

struct Class {
    
  template <typename CLASS>
  struct BuiltInInfoT {
    Field CLASS::*const pField; // member pointer
  };
  
};

struct Object: Class {
  Field field1;
  static inline BuiltInInfoT<Object> field1BuiltInfo = { &Object::field1 };
};

int main()
{
  Object obj;
}
struct字段{};
结构类{
模板
内置结构{
字段类::*const pField;//成员指针
};
};
结构对象:类{
字段1;
静态内联内置field1BuiltInfo={&Object::field1};
};
int main()
{
对象对象对象;
}
这似乎在g++中有效,但在MSVC中却不起作用,对此我感到困惑,我在编译器资源管理器上查看了其他编译器对此的看法。所以,我发现最近的clang甚至最近的ICC(我以前从未使用过)都接受这一点

我在前面一个更简单的示例中尝试了相同的方法,其中我没有使用任何模板:

#include <iostream>

struct Test {
  struct Info { int Test::*p; };
  int a;
  static inline Info infoA = { &Test::a };
  int b;
  static inline Info infoB = { &Test::b };
  
  Test(int a, int b): a(a), b(b) { }
};

#define DEBUG(...) std::cout << #__VA_ARGS__ << ";\n"; __VA_ARGS__ 

int main()
{
  DEBUG(Test test(123, 456));
  DEBUG(std::cout << (test.*(test.infoA.p)) << '\n');
  DEBUG(std::cout << (test.*(test.infoB.p)) << '\n');
}
#包括
结构测试{
结构信息{int Test::*p;};
INTA;
静态内联信息infoA={&Test::a};
int b;
静态内联信息infoB={&Test::b};
测试(inta,intb):a(a),b(b){}
};

#define DEBUG(…)std::cout@Scheff发现了一个可能影响其他重新内联静态成员初始化的问题。这尤其有问题,因为它对编译器资源管理器c++17默认值与MSVC IDE c++17默认值的影响不同查看他的答案和分析:

使用默认的C++设置(C++ 14),不允许内联静态成员。 将设置更改为c++17或更高版本。这是在同一行上进行内联静态初始化的常见原因


然而,在聊天之后,发现c++17正在被使用,但不同的是,它正在与CMake一起使用。显然,CMake和MSBuild解决方案/项目文件之间存在差异。后者有效,前者无效。正在调查中,并将更新结果。

@doug暗示我,他让我的代码在VS2019中运行,没有任何投诉

经过长时间的交谈,他给了我在新创建的VS解决方案中测试上述示例的提示。我所要做的就是启用C++17(
/std:C++17
),然后MSCV毫无怨言地编译所有样本

我必须承认,我通常使用CMake来准备VS解决方案:

project (OFM)

cmake_minimum_required(VERSION 3.10.0)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

include_directories("${CMAKE_SOURCE_DIR}")

file(GLOB sources *.cc)
file(GLOB headers *.h)

add_executable(testOFM
  ${sources} ${headers})
因此,我必须找到VS项目设置中的相关差异。 最后,我发现:

  • VS创建的项目包含
    /permissive-
  • CMake创建的项目没有
在“项目”设置中,它是

- C/C++
  - Language
    - Standards conformance: Yes (/permissive)
微软在线文档:

为编译器指定标准一致性模式。使用此选项可以帮助您识别和修复代码中的一致性问题,从而使代码更加正确和可移植

这正是我想要的:符合标准,便于携带

在我的CMake生成的项目中调整这个选项,我也编译并运行了它

编译器资源管理器上的演示已正确编译(具有足够的命令行参数):

甚至是最初的研究(我的麻烦是从那里开始的):


我想知道的是:当我写我的CMake脚本时,我已经用过了

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
以符合标准和便于携带的确切意图

所以,在CMake中似乎还需要设置其他内容。 (最后的办法可能是平台特定的设置,但如果可能的话,我会调查以找到其他设置。)


关于我的问题,我发现


使用特定于编译器的选项修复CMake脚本后:

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
if (MSVC)
  add_compile_options(/permissive-)
endif()

并再次生成了我的VS解决方案/项目,编译的代码也没有任何问题。

MSVC的设置是
/std:c++17/O2
。我遗漏了什么吗?@Scheff编译器资源管理器可能有问题?在x86和x64版本的MSVC上运行良好发布版和调试版您当前的MSVC是什么?两周前我在本地安装了MSVC19,这是我第一次发现我的问题。我已安装版本
19.27.29112 für x64
。@Scheff Microsoft(r)C/C++优化编译器版本19.27.29112 for x86。在我看来,这套准则完全合理。至少> C++17@Scheff一种可能性是,当您从x86更改为x64时,版本信息没有显示出来,因为它仅为x86设置。我搞砸了,看起来像msvc的bug。不管怎样,这是一个很小的调整,而且很有效:@MarekR外部定义是我当前的解决方案,但它打破了“我更大的概念”:-(太好了!这个模糊的问题可能会再次出现在其他人的面前。特别是当它也出现在编译器浏览器w/o permissive-。很高兴我能提供帮助。