有没有办法让这段代码工作,就像用点符号调用 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
,就像使用静态方法一样。
答案 0 :(得分:6)
您必须使用A::t
代替a.t
,因为typedef类似于static
而a
是A
的实例。
编辑:与我上面所说的相反,它并不总是“像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)