[英]Pointer to member variable as static member
這幾天在擺弄一個數據model的project study,有一種適合我需要的反思。 當我使用最新的穩定版本 g++ 運行我的第一個研究時,我在 Visual Studio 19 中失敗了。太糟糕了,因為后者是我的主要平台……
實際上,我嘗試將指向成員變量的指針存儲到另一個 static 成員變量中。 因此,我真的很希望內聯執行此操作(以適應我更大的概念)。
我將失敗的細節減少到以下 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;
}
感到困惑的是,這似乎在 g++ 中有效,但在 MSVC 中無效,我查看了 Compiler Explorer 上其他編譯器對此的看法。 所以,我發現最近的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');
}
結果是一樣的:g++、clang,ICC 編譯正常但 MSVC 抱怨。
所以,現在我有點不確定。
是否值得報告的 MSVC 錯誤? 還是我在期待一些我不應該依賴的東西?
免責聲明:
當然,我在過去 3 天用谷歌搜索了這個主題,發現了無數關於如何使用成員指針的教程——包括對SO 的回答:C++ 中這個星號 (*) 的含義是什么? — 指向我自己編寫的成員的指針。 也許,我錯過了 essential 關鍵字,但我 promise 我真的很努力。
以防萬一,您想知道我要做什么……
作為coliru 上的 Live Demo的實際項目研究,我從中制作了上面的 MCVE。
更新:
經過長時間的討論,@doug 幫助我發現這似乎是 Visual Studio 屬性設置的主題。 通過一個干凈啟動的項目,我在本地 VS 2019 中運行了上述所有示例。(之前,我像往常一樣使用 CMake 生成的項目。)我將比較兩個 resp 的選項。 VS 項目找出顯着差異並在我發現某些東西時發布更新......
@doug 暗示他讓我的代碼在 VS 2019 中運行,沒有任何抱怨。
經過長時間的交談,他給了我在新創建的 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 項目設置中找到相關的差異。 最后,我找到了它:
/permissive-
在項目設置中,它是
- C/C++
- Language
- Standards conformance: Yes (/permissive)
MS在線文檔:
為編譯器指定標准一致性模式。 使用此選項可幫助您識別和修復代碼中的一致性問題,使其更正確、更可移植。
這正是我想要的:符合標准且便攜。
在我的 CMake 生成的項目中調整這個選項,我也編譯並運行了它。
Compiler Explorer 上的演示已正確編譯(具有足夠的命令行參數):
甚至是最初的研究(我的麻煩從哪里開始):
我想知道的是:當我編寫 CMake 腳本時,我已經使用了
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
確切的意圖是符合標准和便攜。
所以,似乎我必須在 CMake 中設置其他東西。(最后的手段可能是特定於平台的設置,但如果可能的話我會調查尋找其他東西。)
關於我的問題,我發現
CMake 問題 #17068:
MSVC 工具集 14.1+:設置 /permissive- 當 CXX_EXTENSIONS==OFF 時?
在我使用特定於編譯器的選項修復我的 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 解決方案/項目編譯的代碼也沒有任何投訴。
@Scheff 已確定一個問題可能會影響其他人重新內聯 static 成員初始化。 它特別有問題,因為它以不同方式影響編譯器資源管理器 c++17 默認值 v MSVC IDE c++17 默認值。 看他的回答和分析:
為不允許內聯 static 成員的 MSVC 使用默認的 c++ 設置 (c++14)。
將設置更改為 c++17 或更高。 這是在同一行內聯 static 初始化的常見原因。
然而,經過聊天,結果發現 c++17 正在使用,但不同之處在於它與 CMake 一起使用。顯然 CMake 和 MSBuild 解決方案/項目文件之間存在差異。 后者有效,前者無效。 正在調查中,並將更新結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.