从函数模板参数中自动推论对容器的元素类型
Automatically deducing element type of pair container from the function template argument
我想编写一个模板函数,该功能取下一个键值对的容器(例如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);
有更好的方法吗?根据C
的value_type
推断K
和V
的类型是一个好习惯吗?另外,有可能明确通过K
和V
的无效论据。
还要注意如何通过调用remove_const_t
删除密钥类型的constness,因为对于map
,C::value_type::first_type
是const
类型,并且该标准不允许创建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)
是正确的(演示)。但是,如果您需要对不同的模板函数使用类似类型的分解,例如:
....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
很好。如果您不喜欢模板参数中的混乱,则可以将密钥类型直接放在返回类型中,可能是在尾随形式中:
template <typename C>
auto partition_keys(const C& input)
-> vector<vector<remove_const_t<typename C::value_type::first_type>>>;
或依靠正常功能的返回类型扣除额,并完全省略返回类型:
template <typename C>
auto partition_keys(const C& input)
{
vector<vector<remove_const_t<typename C::value_type::first_type>>> result;
//...
return result;
}
相关文章:
- 在C++中,如何通过几种类型从元组中选择多个元素
- 如何为 c++ 的不同变量类型的结构元素创建动态数组?
- 在 C++ 中输出枚举类类型的向量元素
- C++默认情况下,指针类型数组的元素是否保证初始化为 nullptr?
- 如何使用模板根据类型将元素添加到各种容器中
- C++ 未初始化的本地(非全局)int 数组中的元素类型到底是什么?
- OpenCV C++:当垫子类型未知时无法访问垫子元素?
- C++如何乘以包含 std::variant 元素的向量的迭代器?正在执行迭代器类型的转换?
- C++:是否可以编写一个函数,将不同类型的元素附加到变体数组中?
- C++通过别名指针以静默方式将错误的类型分配给数组元素
- 我无法在用forward_as_tuple创建的元组中按类型访问元素
- 如何告诉自动推断向量<bool>元素的非引用类型
- 为什么将函数的返回类型从结构节点*更改为void后,链表的元素没有显示create_ll和显示?
- 如何为基类通用类型创建向量以使用具体类型元素
- 按索引将类类型元素从一个向量复制到另一个 c++
- 如何实现数据结构,就像C 中的数组一样支持不同的类型元素
- 如何在构造具有不同类型元素的向量副本时显式转换
- 处理特定类型元素的任何容器的非模板函数
- *类型元素容器的qt排序
- 如何将两个双数据类型元素转换为一个Point数据类型