繁体   English   中英

具有默认参数的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()
{

}

我有几个问题:

  1. 为什么不编译? (错误C2143语法错误:“令牌2”之前缺少“令牌1”)
  2. 为什么我必须明确指定所有模板参数,甚至是默认参数? (es。考虑到分配器具有默认值,为什么不能仅指定T?)
  3. 在这种情况下将标头与实现分开是正确的吗?

1)

template<typename T, class Allocator>
typename SList<T,Allocator>::iterator SList<T,Allocator>::begin()
^^^^^^^^

这很烦人,但是要习惯它。 编译器假定所有类似模板的内容都是变量,因此,如果是类型,则必须特别说明。

2)编译器需要知道函数定义是针对具有两个模板参数的SList类的,并且两者都可以是任何东西,这不是专门知识。 我意识到您的默认值是默认的,如果缺少默认值也不会模棱两可,但是我认为这主要是为了简化编译器。

3)定义可以在单独的文件中,但不能在其自己的“翻译单元”中(已编译的文件.cpp及其包含在内)。 因此,请勿将其放在.cpp文件中,这只会造成混淆。 模板定义位于.incl文件中并不罕见,该文件包含在标题的底部。 这使编译器感到满意,并且声明和定义仍然分开。

  1. 有两个原因:

    • 这是因为丢失SList<T,Allocator>::在返回类型的前面iteratorbegin

    • iterator是一个依赖类型,因此在两个地方都需要在SList<T, Allocator>::iterator前面输入typename

    • 您不会从具有非void返回类型的函数中返回值; 您需要退货。

  2. 因为名称是SList<T, Allocator> ,所以您必须告诉编译器类的全名,因为您需要能够引用类型名称Allocator ,并且这就是这样。

  3. 您不能这样做,因为编译器要求模板的实现与声明位于同一文件中(除非您执行显式实例化,这会削弱模板的通用性)。 因此,您需要最后将实现#include到接口文件中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM