简体   繁体   中英

c++ template function specialization - wrong number of template arguments?

Okay, so I'm just learning about templates. Anyways, I'm probably (most definitely) doing something wrong, but here's the problem:

My first template function is declared like this:

template<typename T>
std::ostream& printFormatted(T const& container, std::ostream& os = std::cout) {
    //...
}

Then I'm supposed to implement a specialized case for maps, so this is what I tried to do:

template<>
std::ostream& printFormatted<std::map<typename key, typename value>>(std::map<typename key, typename value> const& container, std::ostream& os = std::cout) {
    //...
}

I might be making a mistake with my key/value variables, not sure, but regardless, when trying to compile I get the error message:

error: wrong number of template arguments (1, should be 4)
error: provided for ‘template<class _Key, class _Tp, class _Compare, class _Allocator> class std::__debug::map’

Clearly there's something I don't understand about templates or maps? Someone please help?

Assuming your uses of key and value are meant to be placeholers, you cannot declare template parameters inline with the keyword typename . That is to say, Foo<typename T> is always invalid -- but not to be mistaken with Foo<typename T::bar> which is different altogether. The syntax for specialization looks like:

// Declare template parameters up front
template<typename Key, typename Value>
std::ostream&
printFormatted<std::map<Key, Value> >(std::map<Key, Value> const& container, std::ostream& os = std::cout);

but that wouldn't work because it's a partial specialization and those are not allowed for function templates. Use overloading instead:

template<typename Key, typename Value>
std::ostream&
printFormatted(std::map<Key, Value> const& container, std::ostream& os = std::cout);

This overload will be preferred over the more general template.

What you're doing is not full specialization, but partial specialization, since you still have a template, only a more specialized one. However, you cannot partially specialize functions, so instead, we just provide a new overload. For std::map , you need four template parameters (as the error message helpfully tells you):

template <typename K, typename V, typename Comp, typename Alloc>
std::ostream & printFormatted(const std::map<K,V,Comp,Alloc> & m,
                              std::ostream & o = std::cout)
{
  // ...
}

This answer is not relevant to C++11

If you're using a pre-c++11 compiler, you can't use >> when closing nested templates. You need a space between the > s.

C++ sees >> as a different token than > , and the compiler doesn't use it to close templates. You need a space so the compiler sees a > followed by a > .

The following is more likely to work:

template<>
std::ostream& printFormatted<std::map<typename key, typename value> >(std::map<typename         key, typename value> const& container, std::ostream& os = std::cout) {
    //...
}

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