c++ - 区分 map 和集合的模板

标签 c++ templates stl

set创建通用代码, unordered_set , map , 和 unordered_map ,我需要几个方法,其中处理实际上是不同的。我的问题是让编译器推断出要使用的实现。
考虑这个例子:

#include <map>
#include <unordered_set>
#include <string>
#include <iostream>

using namespace std;

static unordered_set<string>    quiet;
static map<const string, const string>  noisy;

template <template <typename ...> class Set, typename K>
static void insert(Set<K> &store, const string &key, const string &)
{
    cout << __PRETTY_FUNCTION__ << "(" << key << ")\n";
    store.insert(key);
}

template <template <typename ...> class Map, typename K, typename V>
static void insert(Map<K, V> &store, const string &key, const string &v)
{
    cout << __PRETTY_FUNCTION__ << "(" << key << ", " << v << ")\n";
    store.insert(make_pair(key, v));
}

int
main(int, char **)
{
    insert(noisy, "cat", "meow");
    insert(quiet, "wallaby", ""); /* macropods have no vocal cords */

    return 0;
}
尽管 cat 行有效,但小袋鼠行会从编译器 (clang-10) 中触发以下错误:
t.cc:22:8: error: no matching member function for call to 'insert'
        store.insert(make_pair(key, v));
        ~~~~~~^~~~~~
t.cc:29:2: note: in instantiation of function template specialization
      'insert<unordered_set, std::__1::basic_string<char>, std::__1::hash<std::__1::basic_string<char> > >' requested here
        insert(quiet, "wallaby", ""); /* macropods have no vocal cords */
错误很明显,quiet ,这是一个 unordered_set , 被路由到 map 的插入实现也是——而不是为 unordered_set 制作的.
现在,这并非完全没有希望——如果我:
  • 详细说明所有模板参数——包括可选参数(比较器、分配器等)
    template <template <typename ...> class Set, typename K, typename A, typename C>
    static void insert(Set<K, A, C> &store, const string &key, const string &)
    ...
    template <template <typename ...> class Map, typename K, typename V, typename A, typename C>
    static void insert(Map<K, V, A, C> &store, const string &key, const string &v)
    
  • 更换 unordered_setset .

  • 程序将按预期编译和工作——编译器会区分 set来自 map通过每个模板采用的参数数量(三个对四个)。
    但是unordered_set具有与 map 相同数量的参数(四)...和unordered_map有五个参数,所以它不会被路由到 map 处理方法......
    如何为要处理的两种类型的集合收紧集合处理函数的声明?
    我该如何处理这两个 map s 和 unordered_map s 在同一个代码中?

    最佳答案

    您可以使用 SFINAE 技术基本上说:仅当 insert 时才考虑此重载。内部调用是格式良好的。例如。像这样:

    template <template <typename ...> class Set, typename K>
    static auto insert(Set<K> &store, const string &key, const string &)
      -> std::void_t<decltype(store.insert(key))>
    {
        cout << __PRETTY_FUNCTION__ << "(" << key << ")" << endl;
        store.insert(key);
    }
    
    template <template <typename ...> class Map, typename K, typename V>
    static auto insert(Map<K, V> &store, const string &key, const string &v)
      -> std::void_t<decltype(store.insert(make_pair(key, v)))>
    {
        cout << __PRETTY_FUNCTION__ << "(" << key << ", " << v << ")" << endl;
        store.insert(make_pair(key, v));
    }
    
    Demo

    关于c++ - 区分 map 和集合的模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65472996/

    相关文章:

    从完整二叉搜索树顺序转换为排序顺序的算法,反之亦然

    c++ - 要学习STL,关于c++应该了解什么?

    c++ - 如何使用 curlpp 方法使用 POST 上传文件和 json 数据

    c++ - 指针算术题(数组大小)[C++]

    c++ - std::fstream 和 Boost Iostreams 库之间的区别

    c++ - 如何使用 enable_if 和模板特化 c++?

    c++ - 为整数序列的每个参数调用一个 void 函数

    c++ - 近似 e^1 :( 的错误逻辑

    c++ - 开关盒中的变量 : UB or compiler bug?

    c++ - 为什么要将结构包装在匿名 union 中? (STL msvc 实现)