如何使用此类的实例引用类中的typedef?

时间:2012-04-14 20:57:21

标签: c++ static typedef

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

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,而是通过t实例“调用”A,就像使用静态方法一样。

4 个答案:

答案 0 :(得分:6)

您必须使用A::t代替a.t,因为typedef类似于staticaA的实例。


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

  

可以使用qualified-id表达式X :: s引用类X的静态成员;没有必要   使用类成员访问语法(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;

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

答案 1 :(得分:1)

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

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

请注意,如果要在课外使用,则必须公开显示typedef引入的类型别名。如果你有:

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

然后在上面的示例中使用A :: t会产生编译器错误(“无法访问private typedef ...”)。您需要使用public访问者说明符:

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

答案 2 :(得分:1)

你可以这样做:

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

decltype特定于C ++ 11

答案 3 :(得分:0)

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

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

有关范围解析运算符的更多信息,请查看C++ Scope Resolution Operator ::