簡體   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