Tom. W Tom. W - 25 days ago 15
C++ Question

template argument deduction - boost::unordered_map

when I was reading the boost::unordered_map source code, I'was confused about the definition of the class, like below:

template <class K, class T, class H, class P, class A>
class unordered_map
{
public:
typedef K key_type;
typedef std::pair<const K, T> value_type;
typedef T mapped_type;
typedef H hasher;
typedef P key_equal;
typedef A allocator_type;
private:
typedef boost::unordered::detail::map<A, K, T, H, P> types;
typedef typename types::traits allocator_traits;
typedef typename types::table table;
...
private:
table table_;

public:
// constructors
explicit unordered_map(
size_type = boost::unordered::detail::default_bucket_count,
const hasher& = hasher(),
const key_equal& = key_equal(),
const allocator_type& = allocator_type());
...
};


There's no default value for class H, class P and class A, then why user can declare a map instance like
boost::unordered_map<Key, Value> map
?
I didn't find any guide. Could anyone help? A detailed document/link would be best.

Answer

If you start looking at the first header file, the one that you actually #include, you are going to find the declaration for this template, that specifies all the defaults for the template parameters. (That declaration may not be in the actual header file, but in an internal header file being #included from there).

The declaration gets compiled first, and declares the defaults, and what you're seeing here is the actual template definition.

The initial template declaration already specifies the defaults for the template parameters, and it does not need to be specified in this template definition (and, in fact, it will be a compilation error if it did).

A brief example:

// Initial declaration

template<typename T=int> class foo;

// Definition

template<typename T> class foo {};

// Usage
foo<> bar;

The actual Boost header files are quite complex in their structure, with the declaration and the definition of the templates spread across separate files, for various sundry reasons, which get assembled in the right order by the actual header file you #include in your code.