Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

templates

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?

like image 264
Fault Avatar asked Dec 18 '25 10:12

Fault


2 Answers

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.

like image 195
Luc Danton Avatar answered Dec 20 '25 01:12

Luc Danton


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)
{
  // ...
}
like image 40
Kerrek SB Avatar answered Dec 19 '25 23:12

Kerrek SB



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!