C++中哪个特性允许模板类在没有模板参数的情况下引用自身?

6

给定:

template <typename T>
class C {
    C & operator ++ () { ... }
};

为什么/如何允许C声明类型为C的变量和函数,而不需要命名为C<T>?在处理具有许多参数的模板时,我没有真正考虑过这个问题,因为拼写“自身类型”会很麻烦。你需要知道这方面的任何特殊情况吗?
3个回答

6

[n3290: 14.6.1/1]: 类模板与普通(非模板)类一样,有一个注入类名(第9条款)。该注入类名可以用作模板名称类型名称。当它在模板参数列表中使用时,作为模板模板参数模板参数,或者作为友好类模板声明的限定类型说明符中的最终标识符时,它引用了类模板本身。否则,它等价于跟随在封闭在<>中的类模板的模板参数之后的模板名称

看起来,它仅仅是一个方便的特性。


3
很惊奇,当我引用了错误的段落时,有两个人给这篇文章点了赞;-)引用标准的力量无法否认——显然是指标准的“任何”部分! - Lightness Races in Orbit
啊哈,我遗漏的概念是 injected-class-name。谢谢! - Ben Jackson
在C++11中,类名不会被注入,因此我认为这会导致错误。 - Mr.Anubis
@Mr.Anubis:上面的引用来自C++11,它说“类模板有一个injected-class-name”。这个测试用例并不能完全证明,因为我不相信实现已经“完全”遵循了C++11语言规则,但我认为它肯定足够好了。 - Lightness Races in Orbit
请查看这个链接:http://www.ideone.com/wAcHv,这就是为什么我说过那句话的原因。 - Mr.Anubis
@Mr.Anubis:看起来已经编译成功了...也许我误解了你想表达的意思。 - Lightness Races in Orbit

2

C语言为什么/如何允许声明类型为C的变量和函数,而不需要命名为C?

这只是按照规范进行的。模板的名称被注入到其主体中,并表示实际类型(带有参数)。

我需要知道这方面的任何特殊情况吗?

没有什么严重的问题。你只需要记住,这不适用于基类,所以要使用CRTP,你必须这样做:

template <class T>
class A : public Base<A<T> > // not Base<A>

2
除非“Base”期望一个模板模板参数。 ;) - Xeo
@Xeo:是的,在CRTP中,基类期望派生类型。 - jpalecek
一者不排除另一者。 - Xeo

2

这只是一种语法糖。

如果你需要更改模板参数,不必改变方法签名非常方便。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接