为什么模板类的成员需要通过其模板类的参数进行参数化
Why do members of a template class need to be parameterized by the parameters of their template class
在Stroustrup的书(第4版-首次印刷(的668页中,您会发现以下模板类的示例?
template<typename C>
class String{
public:
String();
...
private:
int sz;
C* ptr;
};
在第679页,作者写道:
模板类的成员本身就是由参数化的模板其模板类的参数。定义此类成员时在其类之外,它必须显式声明为模板。对于示例:
template<typename C> String<C>::String() :sz(0), ptr(ch) { ch[0] = {}; }
这个例子中有一个明显的错误。变量ch
在上面没有任何意义。但这与我的问题无关。我想知道的是,为什么上面的构造函数不能在没有参数C
的情况下定义,如下所示?
template<typename C>
String::String()
: sz(0), ptr(nullptr)
{
}
String
是模板的名称,而不是类。模板甚至不是类型,因此它没有成员。然而,模板专业化是一个类。您需要插入C
,以便指定您在本定义中所指的专业化。
现在恰好定义本身就是一个模板,但这是因为你正在为一系列专业定义东西。然而,事实仍然是,您需要明确地命名这些专业。
最后,只需要指定一次专门化的原因是在类模板专门化的范围内以特殊的方式处理模板名称。在该范围内,模板名称指的是注入的类名,指的是专门化本身。这就是的原因
template<typename C>
String<C>::String<C>()
:sz(0), ptr(ch)
{
}
可以写成…
template<typename C>
String<C>::String()
:sz(0), ptr(ch)
{
}
由于String<C>
已经建立了我们所指的专门化,并且我们在它的范围内,所以我们可以使用具有特殊含义的String
作为注入的类名。
C++本可以用一个特殊的规则来设计,使这个琐碎而常见的情况能够像你期望的那样工作。不过,当前的规则更一致,因为它们在更复杂的情况下仍然可以工作。
特别要考虑以下内容:
template<typename C, int I> class String { };
template<typename C> class String<C,0> { String(); };
template<typename C> class String<C,1> { String(); };
这是一个类模板,具有两个部分专门化。
现在第一个ctor被定义为
template<typename C> String<C,0> :: String() { }
您可以看到,模板参数列表有一个额外的参数,0
,它指示特定的专业化。部分专业化改变了基础模板的一些但不是所有模板参数。您必须指定哪些参数可以变化,哪些参数具有固定值。
相关文章:
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 使用指向成员的指针将成员函数作为参数传递
- 如何将lambda作为模板类的成员函数参数
- 将成员函数指针作为参数传递给模板方法
- c++构造函数成员初始化:传递参数
- 使用带有 ref 参数的成员函数创建线程时出现编译错误
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 模板化检查是否存在带有参数列表的类成员函数?
- 如何将类成员方法的参数列表自动填充写入可变参数?
- 为什么我需要在成员发起器列表中重复基类的模板参数?
- C++向量默认为成员参数
- 将成员函数作为构造函数参数调用时出错 "Variable is not a type name"
- 可变参数模板参数扩展 类型为 std::function 的类成员
- 绑定到可变参数成员函数
- C/C++ 包含点的宏参数(成员访问运算符)
- 将const char * const参数成员分配给新值
- 基于模板参数成员函数参数的模板专用化
- 如何访问可变参数成员
- 可变类参数成员变量的异构存储
- 非模板类中的可变参数成员