3

我想出了利用decltype在.cpp文件中定義靜態成員,然後使用這個宏的想法:使用decltype定義靜態成員(智能感知不同意)

#define DEFINE_SYMBOL(x) decltype(x) x 

這種方式,例如如果類Foo聲明static int bar,我可以做Foo.cpp中的以下內容:

DEFINE_SYMBOL(Foo::bar) = 1337; 

這似乎有點「哈克」,但它有具有彈性在原始符號類型變化的優勢。例如,如果bar更改爲foo.hpp中的未簽名,則不需要更改foo.cpp。當成員類型複雜時,閱讀也更容易。

但是,如果靜態成員是私有的,則在Visual Studio 2015中,Intellisense會抱怨使用decltype(稱爲無法訪問)。抱怨很有道理,雖然程序編譯得很好。現在,我的問題是,Intellisense是錯誤的,還是不推薦使用decltype(以及爲什麼)?

+1

gcc和clang接受它([Demo](http://coliru.stacked-crooked.com/a/c1bde595c6627cc7)),Msvc接受它。我認爲這是一個intellisense錯誤。 – Jarod42

+0

看起來像IntelliSense認爲'DEFINE_SYMBOL(Foo :: bar)'是一個函數調用而不是宏。 –

回答

1

智能感知是不正確,GCC和鏗鏘編譯一個類似的計劃,我們可以看到C++草案標準節11[class.access]說:

在第11章的所有訪問控制影響的能力從特定實體的聲明中訪問類成員名稱,包括宣佈的實體名稱前的聲明部分,並且如果實體是類,則該類成員的定義出現在類的成員之外 - 規範。 [注意:此訪問也適用於對構造函數,轉換函數和析構函數的隱式引用。 末端注] [實施例:

class A { 
typedef int I; // private member 
I f(); 
friend I g(I); 
static I x; 
template<int> struct Q; 
template<int> friend struct R; 
protected: 
struct B { }; 
}; 
A::I A::f() { return 0; } 
A::I g(A::I p = A::x); 
A::I g(A::I p) { return 0; } 
A::I A::x = 0; 
template<A::I> struct A::Q { }; 
template<A::I> struct R { }; 
struct D: A::B, A { }; 

在這裏,所有的使用A ::我都能很好地形成,因爲A :: F,A :: x和A :: Q爲A類的成員並且g和 R是類A的朋友。例如,這意味着首次使用A :: I的訪問檢查必須推遲到 ,直到確定A :: I的這種使用是返回類型類似地, 使用A :: B作爲基指定符是格式良好的,因爲D是從A派生的,所以必須延遲基指定符 的檢查,直到整個基指定符爲止。名單已被看到。 - 示例]