使用 decltype 定义静态成员(Intellisense 不同意)

Using decltype to define static members (Intellisense disagrees)

我想到了使用 decltype 在 .cpp 文件中定义静态成员,然后使用这个宏:

#define DEFINE_SYMBOL(x) decltype(x) x

这样,例如,如果 class Foo 声明 static int bar,我可以在 foo.cpp 中执行以下操作:

DEFINE_SYMBOL(Foo::bar) = 1337;

这看起来有点"hacky",但它的优点是可以适应原始符号类型的变化。例如,如果 foo.hpp 中的 bar 更改为 unsigned,我就不需要更改 foo.cpp。当成员类型复杂时,也更容易阅读。

但是,如果静态成员是私有的,在 Visual Studio 2015 年,Intellisense 会抱怨使用 decltype(说它不可访问)。抱怨是有道理的,尽管程序编译得很好。现在,我的问题是,Intellisense 是错误的,还是不推荐使用 decltype(以及为什么)?

Intellisense 不正确,gcc 和 clang 编译的程序相似,我们可以看到 C++ 标准草案部分 11 [class.access] 说:

All access controls in Clause 11 affect the ability to access a class member name from the declaration of a particular entity, including parts of the declaration preceding the name of the entity being declared and, if the entity is a class, the definitions of members of the class appearing outside the class’s member-specification. [ Note: this access also applies to implicit references to constructors, conversion functions, and destructors. —end note ] [ Example:

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 { };

Here, all the uses of A::I are well-formed because A::f, A::x, and A::Q are members of class A and g and R are friends of class A. This implies, for example, that access checking on the first use of A::I must be deferred until it is determined that this use of A::I is as the return type of a member of class A. Similarly, the use of A::B as a base-specifier is well-formed because D is derived from A, so checking of base-specifiers must be deferred until the entire base-specifier-list has been seen. —end example ]