简体   繁体   中英

C++ template with default parameter

It's the first time I'm trying to implement a custom STL compatible container with its iterator, but I'm having some trouble with templates syntax and usage. This is part of my header file:

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();
    ...
    };}

Let's consider for example begin() method. I wrote the following (in a .cpp file) that doesn't compile:

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()
{

}

I have several questions:

  1. Why this doesn't compile? (error C2143 syntax error : missing 'token1' before 'token2')
  2. Why do I have to nominate explicetly all the template parameter, even the defaulted ones? (es.why can't I specify only T considering that Allocator has a default value?)
  3. Is right to separate the header from implementation in this situation?

1)

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

It's irritating, but get used to it. The compiler assumes that all templated things like that are variables, so if it's a type, you have to say so specifically.

2) The compiler needs to know that the function definition is for the SList class that has two template parameters, and that both can be anything, this isn't a specialization. I realize yours is defaulted and wouldn't be ambiguous if the default was missing, but I think it's to simplify compilers primarily.

3) The definitions can be in a separate file, but not in it's own "Translation Unit" (a compiled file .cpp and it's includes). So, don't put it in a .cpp, that's just confusing. It's not uncommon for template definitions to be in a .incl file, which is included at the bottom of the header. This makes the compiler happy, and you still have separation of declaration and definition.

  1. For a couple of reasons:

    • You are missing SList<T,Allocator>:: in front of the return type iterator of begin

    • iterator is a dependent type so you need typename in front of SList<T, Allocator>::iterator in both places

    • You don't return a value from a function that has a return type other than void ; you need to return something.

  2. Because the name is SList<T, Allocator> and you must tell the compiler the full name of the class, because you need to be able to refer to the type name Allocator , and because that's just how it is.

  3. You can't because the compiler requires the implementation of the templates to be in the same file as the declaration (unless you do explicit instantiation which nerfs the genericity of templates). So you'll need to #include the implementation into the interface file at the end.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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