带有默认参数的C++模板模板参数

mat*_*ots 8 c++ templates

我有一个类需要使用某种地图.默认情况下,我想使用std::map,但我也希望让用户能够根据需要使用不同的东西(例如std::unordered_map,甚至用户创建一个).

所以我的代码看起来像

#include <map>

template<class Key, template<class, class> class Map = std::map>
class MyClass {
};

int main() {
  MyClass<int> mc;
}
Run Code Online (Sandbox Code Playgroud)

但是,g ++抱怨道

test.cpp:3:61: error: template template argument has different template parameters than its corresponding template template parameter
template<class Key, template<class, class> class Map = std::map>
                                                            ^
test.cpp:8:14: note: while checking a default template argument used here
  MyClass<int> mc;
  ~~~~~~~~~~~^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/map:781:1: note: too many template parameters in template template argument
template <class _Key, class _Tp, class _Compare = less<_Key>,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:3:21: note: previous template template parameter is here
template<class Key, template<class, class> class Map = std::map>
                    ^~~~~~~~~~~~~~~~~~~~~~
1 error generated.
Run Code Online (Sandbox Code Playgroud)

所以看起来g++不高兴std::map有默认参数.

有没有办法可以允许Map任何类型的模板可以接受至少两个模板参数?

如果可以的话,我宁愿坚持使用C++ 98,但我对C++ 11持开放态度.

Col*_*mbo 7

问题是你的模板模板参数只有两个模板参数map,而有四个模板参数.

template<class Key, template<class, class, class, class> class Map = std::map>
class MyClass {
};
Run Code Online (Sandbox Code Playgroud)

要么

template<class Key, template<class...> class Map = std::map>
class MyClass {
};
Run Code Online (Sandbox Code Playgroud)

应该编译.
但是,要避免此类问题,请尝试改为使用地图类型,并通过相应的成员typedef提取密钥类型.例如

template <class Map>
class MyClass {
    using key_type = typename Map::key_type;
};
Run Code Online (Sandbox Code Playgroud)