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

Using decltype to define static members (Intellisense disagrees)

本文关键字:Intellisense 不同意 静态成员 decltype 定义 使用      更新时间:2023-10-16

我提出了使用decltype在.cpp文件中定义静态成员的想法,然后使用以下宏:

#define DEFINE_SYMBOL(x) decltype(x) x

例如,通过这种方式,如果类Foo声明static int bar,我可以在foo.cpp中执行以下操作:

DEFINE_SYMBOL(Foo::bar) = 1337;

这看起来有点"粗糙",但它的优点是对原始符号类型的变化具有弹性。例如,如果bar在foo.hpp中变为unsigned,我就不需要更改foo.cpp。当成员的类型复杂时,它也更容易读取。

然而,如果静态成员是私有的,那么在Visual Studio 2015中,Intellisense会抱怨使用decltype(称其不可访问)。尽管程序编制得很好,但抱怨还是有道理的。现在,我的问题是,Intellisense是错的,还是不建议使用decltype(以及为什么)?

Intellisense不正确,gcc和clang都编译了类似的程序,我们可以看到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::I的所有用法都是正规的,因为A::f、A::x和A::Q是类A和g的成员,并且R是类A的朋友。这意味着,例如,第一次使用A:时的访问检查:I必须是推迟到确定使用A::I作为类A的成员的返回类型。类似地,使用A::B作为基说明符是正确的格式,因为D是从A派生的,所以检查基说明符必须推迟,直到看到整个基说明符列表为止--结束示例]