使用 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 ]
我想到了使用 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 ]