1

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

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调用” ,就像您可以使用静态方法一样。tA

4

4 回答 4

7

您必须使用A::t,而不是a.t因为 typedef 就像static并且aA.


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

可以使用限定 ID 表达式 X::s; 来引用类 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
}

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

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

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

但是,我看不到它的实际用途(好吧,也许在宏中,但每个人都知道模板更好)。

于 2012-04-14T21:00:31.093 回答
1

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

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

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

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

然后像上面的例子那样使用 A::t 会产生编译器错误(“cannot access private typedef...”)。您需要使用public访问器说明符:

class A
{
    static void f(){}
public:
    typedef int t;
};
于 2012-04-14T21:05:32.187 回答
1

你可以这样做:

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

decltype 特定于 C++11

于 2012-04-14T21:20:40.640 回答
0

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

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

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

于 2012-04-14T21:01:08.247 回答