带有默认参数的C++模板
C++ template with default parameter
这是我第一次尝试用迭代器实现自定义STL兼容容器,但我在模板语法和用法方面遇到了一些问题。这是我头文件的一部分:
namespace unstd {
template<typename T,class Allocator = std::allocator<T>>
class SList
{
public:
typedef typename Allocator::value_type value_type;
typedef typename size_t size_type;
typedef typename Allocator::template rebind<T>::other allocator_type;
typedef typename Allocator::reference reference;
typedef typename Allocator::const_reference const_reference;
typedef typename T* pointer;
typedef typename const T* const_pointer;
typedef typename ptrdiff_t difference_type;
typedef typename SList_Iterator_Forward<T> iterator;
typedef typename const SList_Iterator_Forward<T> const_iterator;
....
/*----- ITERATORS -------*/
iterator begin();
...
};}
让我们考虑例如begin()方法。我写了以下内容(在.cpp文件中),但没有编译:
template<typename T, class Allocator>
iterator SList<T,Allocator>::begin()
{
}
//neither the following compile
template<typename T, class Allocator>
SList<T,Allocator>::iterator SList<T,Allocator>::begin()
{
}
我有几个问题:
- 为什么不编译?(错误C2143语法错误:"token2"之前缺少"token1")
- 为什么我必须明确地指定所有的模板参数,甚至是默认的参数?(考虑到Allocator有默认值,为什么我不能只指定t?)
- 在这种情况下,将头与实现分离是正确的吗
1)
template<typename T, class Allocator>
typename SList<T,Allocator>::iterator SList<T,Allocator>::begin()
^^^^^^^^
这很烦人,但要习惯它。编译器假设所有模板化的东西都是变量,所以如果它是一个类型,你必须明确地说。
2) 编译器需要知道函数定义是针对具有两个模板参数的SList
类的,并且这两个参数都可以是任何东西,这不是专门化。我知道你的是默认的,如果没有默认的,也不会模棱两可,但我认为这主要是为了简化编译器。
3) 定义可以在一个单独的文件中,但不能在它自己的"翻译单元"(一个编译的文件.cpp及其包含)中。所以,不要把它放在.cpp中,这只是令人困惑。模板定义位于.incl文件中并不罕见,该文件包含在标头的底部。这让编译器很高兴,并且您仍然可以分离声明和定义。
-
原因如下:
-
begin
的返回类型iterator
前面缺少SList<T,Allocator>::
-
iterator
是一个依赖类型,所以在两个位置中,SList<T, Allocator>::iterator
前面都需要typename
-
对于返回类型不是
void
的函数,您不会返回值;你需要归还一些东西。
-
-
因为名称是
SList<T, Allocator>
,您必须告诉编译器类的全名,因为您需要能够引用类型名称Allocator
,并且因为它就是这样。 -
您不能这样做,因为编译器要求模板的实现与声明在同一个文件中(除非您进行显式实例化,从而削弱模板的通用性)。因此,您需要在最后将实现
#include
放入接口文件中。
相关文章:
- .cpp和.h文件中的模板专用化声明
- C++模板来检查友元函数的存在
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 如何在c++中为模板函数实例创建快捷方式
- 使用C++中的模板和运算符重载执行矩阵运算
- 有人能分解一下这个c++模板的语法吗
- 如何在c++17中制作一个模板包装器/装饰器
- 模板化建造师专业化
- 调用专用模板时出错"no matching function for call to [...]"
- 模板元程序查找相似的连续类型名称
- 如何在C++20中创建模板别名的推导指南
- 没有名称的C++模板参数
- 具有重复类型的C++可变模板
- 如何将enable-if与模板参数和参数包一起使用
- 没有用于初始化C++中的变量模板的匹配构造函数