c++ - 从函数模板参数自动推断对容器的元素类型

标签 c++ templates std-pair

我想编写一个模板函数,它接受一个键值对容器(例如 map<K,V>vector<pair<K,V>> )并返回一个键容器容器。例如:

template<typename C, typename K, typename V>
vector<vector<K>> partition_keys(const C& input)
{
    vector<vector<K>> result;
    ...
    // do something
    for (const auto &pair : input)
    {
        cout << pair.first << "," << pair.second << std::endl;
    }
    ...
    return result;
}

我想这样调用它:

// map
map<string, string> product_categories;
partition_keys(product_categories); // doesn't work
partition_keys<map<string, string>, string, string>(product_categories); // have to do this
// vector
vector<pair<string, string>> movie_genres;
partition_keys(movie_genres); // doesn't work
partition_keys<vector<pair<string, string>>, string, string>(movie_genres); // have to do this

但是,如果不显式指定,编译器无法推导出模板参数 K 和 V。我希望该函数适用于具有任何类型对的任何容器;所以我想避免为 map<K,V> 编写单独的模板函数, list<pair<K,V>> , vector<pair<K,V>>

所以,我不得不按如下方式修改模板函数签名,以使其按我想要的方式工作:

template<typename C, 
         typename K = remove_const_t<C::value_type::first_type>, 
         typename V = C::value_type::second_type>
vector<vector<K>> partition_keys(const C& input);

有更好的方法吗?推断 K 的类型是一个好习惯吗?和 V基于 value_typeC ?此外,调用者有可能为 K 显式传递无效参数。和 V .

另请注意我是如何通过调用 remove_const_t 删除键类型的常量的因为对于 map , C::value_type::first_typeconst类型和标准不允许创建 const 的集合类型。

最佳答案

您的做法是正确的,更具体地说:

template<typename C,
         typename Pair = typename C::value_type,
         typename Key = std::remove_const_t<typename Pair::first_type>,
         typename Value = typename Pair::first_type
        >
vector<vector<Key>> partition_keys(const C& input)

是正确的(Demo) .但是,如果您需要对不同的模板函数使用相似的类型分解,例如:

....repeat above templated type decomposition....
vector<vector<Key>> sorted_keys(const C& input);

....repeat above templated type decomposition....
vector<vector<Key>> filtered_keys(const C& input);

可能打字太多了。在这种情况下,您可以制作一个简单的特征类来帮助您。

template<typename T>
struct PTraits{
    using pair_type  = typename T::value_type;
    using key_type   = std::remove_const_t<typename pair_type::first_type>;
    using value_type = typename pair_type::second_type;
};

template<typename T>
using KeyTypper = typename PTraits<T>::key_type;

然后用作...

template<typename C, typename Key = KeyTypper<C>>
vector<vector<Key>> partition_keys(const C& input);

template<typename C, typename Key = KeyTypper<C>>
vector<vector<Key>> sorted_keys(const C& input);

template<typename C, typename Key = KeyTypper<C>>
vector<vector<Key>> filtered_keys(const C& input);

Demo

关于c++ - 从函数模板参数自动推断对容器的元素类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42607969/

相关文章:

c++ - 位域 "In-class initialization"结果为 "error: lvalue required as left operand of assignment"

c# - 将 Stream 数据映射到 C# 中的数据结构

c++ 模板特化与 std::enable_if 不工作

c++ - std::thread 从模板函数调用模板函数

c++ - 如何根据 .first 值从 std::pair 的 std::vector 中删除元素?

c++ - Std::pair/ostringstream 构造函数语法

c++ - 如何防止基类的 protected 成员在子类的第二级中仍然被访问?

c++ - std::vector 删除满足某些条件的元素

带约束的 C# 模板

c++ - 对值读取错误 C++