如何在具有此类实例的类中引用 typedef

how to reference a typedef within a class with an instance of such class?

本文关键字:实例 引用 typedef      更新时间:2023-10-16

有没有办法让这段代码工作,就像用点符号调用静态函数一样?

struct A{
    static void f(){ }
    typedef int t;
};
template<typename T> void f(){}
int main(){
    A a;
    a.f();          //legit
    f<a.t>();       //‘a’ cannot appear in a constant-expression, ‘.’ cannot appear in a constant-expression
    a.t somevar;    //invalid use of ‘A::t’
    f<a::t>();      //‘a’ cannot appear in a constant-expression
    a::t somevar;   //‘a’ is not a class, namespace, or enumeration
}

编辑:伙计们,请在发布之前阅读问题并测试您的代码。这里的要点不是使用A::t而是通过A的实例"调用"t,就像你可以使用静态方法一样。

你必须

使用A::t而不是a.t,因为typedef就像static,而aA的一个实例。


编辑:与我上面所说的相反,它并不总是"像static"。 对于静态成员,有以下特殊规则:

类 X 的静态成员 s 可以使用限定 id 表达式 X::s 来引用;没有必要 使用类成员访问语法 (5.2.5) 引用静态成员。可以引用静态成员 以使用类成员访问语法,在这种情况下,将计算对象表达式。 [ 示例:

struct process {
  static void reschedule();
};
process& g();
void f() {
  process::reschedule(); // OK: no object necessary
  g().reschedule();      // g() is called
}

由于typedef不是静态成员,因此此语法无效。

给定实例a而不是这个语法糖,获取t的唯一方法是获取它的类型。 C++11 为我们提供了一个工具:

typedef decltype(a) a_type;
f<a_type::t>();
a_type::t somevar;

但是,我认为它没有实际用途(好吧,也许在宏中,但每个人都知道模板更好)。

您需要使用范围解析运算符(并从 main 返回 int 值):

int main()
{
    A a;
    A::t somevar = 0;
    return 0;    
}

请注意,如果要在类外部使用它,则随 typedef 引入的类型别名必须公开可见。如果您有:

class A
{
    static void f(){}
    typedef int t;
};

然后像上面的例子一样使用 A::t 会产生编译器错误("无法访问私有 typedef...")。您需要使用public访问器说明符:

class A
{
    static void f(){}
public:
    typedef int t;
};
你可以

这样做:

typedef decltype (a) AT;
typedef AT::t T;
f<T>();
T somevar;

decltype 特定于 C++11

您将需要使用范围解析运算符,因此可能需要

f<A::t>();
A::t somevar;

有关范围解析运算符的详细信息,请查看C++范围解析运算符::。