繁体   English   中英

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

[英]C++ template parameter with default parameters

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

所以我的代码看起来像

#include <map>

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

int main() {
  MyClass<int> mc;
}

但是,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.

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

有没有一种方法可以让Map成为可以接受至少两个模板参数的任何类型的模板?

如果可以,我更愿意坚持使用 C++98,但我对 C++11 持开放态度。

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

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

或者

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

应该编译
但是为了避免这样的问题,尽量取map类型,通过对应的成员typedef提取key类型。 例如

template <class Map>
class MyClass {
    using key_type = typename Map::key_type;
};

您的代码将在 C++17 中编译。 C++ 核心工作组 ( CWG 150 ) 的长期缺陷报告已在 C++17 中及时解决(由P0522R0 提供)。

cppreference.com也在此处讨论了这一点,并提供了一个有用的示例:

template<class T> class A { /* ... */ };
template<class T, class U = T> class B { /* ... */ };
template <class ...Types> class C { /* ... */ };

template<template<class> class P> class X { /* ... */ };
X<A> xa; // OK
X<B> xb; // OK in C++17 after CWG 150
         // Error earlier: not an exact match
X<C> xc; // OK in C++17 after CWG 150
         // Error earlier: not an exact match

使用我的 GCC (8.3.0) 版本进行测试,我发现使用-std=c++17标志将成功编译您的程序; 使用早期版本的 C++(例如-std=c++14-std=c++11 )将失败。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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