C++概念和`std::is_same`的模板参数推导问题
Template parameter deduction problem with C++ concepts and `std::is_same`
如果我尝试编写一个受概念限制为 std::map
和 std::unordered_map
且具有 Key
键和 Element
元素的函数,它无法推断出Key
输入以下代码。
template<typename A, typename B>
concept is_same_as = std::is_same<A, B>::value;
template<typename T, typename Key, typename Element>
concept map_type_of =
is_same_as<T, std::map<Key, Element>> ||
is_same_as<T, std::unordered_map<Key, Element>>;
template <typename T, typename Key, typename Element>
requires map_type_of<T,Key,Element>
inline std::list<Key> map_extract_keys(T const& a) {
std::list<Key> output;
for (auto const& element : a) {
output.push_back(element.first);
}
return output;
}
std::map<std::string, int> map_example;
auto keys = map_extract_keys(map_example);
它给出的实际错误:
candidate: ‘template<class T, class Key, class Element> requires map_type_of<T, Key, Element> std::__cxx11::list<Key> map_extract_keys(const T&)’
inline std::list<Key> map_extract_keys(T const& a) {
note: template argument deduction/substitution failed:
note: couldn’t deduce template parameter ‘Key’
有什么办法允许自动扣除吗?
您的 map_type_of
概念无法帮助您解决更简单的概念
template<typename T>
concept is_map = std::ranges::range<T>
&& std::semiregular<typename T::key_type>
&& std::semiregular<typename T::mapped_type>;
template <typename T>
requires is_map<T>
inline std::list<typename T::key_type> map_extract_keys(T const& a) {
std::list<typename T::key_type> output;
for (auto const& [key, value] : a) {
output.push_back(key);
}
return output;
}
作为奖励,它允许 boost::bimap<...>::left_map
等
我想只要对您的代码进行最少的更改,您就可以做到:
template <template <typename, typename> class T, typename K, typename E>
requires map_type_of<T<K,E>, K, E>
inline auto map_extract_keys(T<K,E> const& a) {
std::list<K> output;
for (auto const& element : a) {
output.push_back(element.first);
}
return output;
}
如果我尝试编写一个受概念限制为 std::map
和 std::unordered_map
且具有 Key
键和 Element
元素的函数,它无法推断出Key
输入以下代码。
template<typename A, typename B>
concept is_same_as = std::is_same<A, B>::value;
template<typename T, typename Key, typename Element>
concept map_type_of =
is_same_as<T, std::map<Key, Element>> ||
is_same_as<T, std::unordered_map<Key, Element>>;
template <typename T, typename Key, typename Element>
requires map_type_of<T,Key,Element>
inline std::list<Key> map_extract_keys(T const& a) {
std::list<Key> output;
for (auto const& element : a) {
output.push_back(element.first);
}
return output;
}
std::map<std::string, int> map_example;
auto keys = map_extract_keys(map_example);
它给出的实际错误:
candidate: ‘template<class T, class Key, class Element> requires map_type_of<T, Key, Element> std::__cxx11::list<Key> map_extract_keys(const T&)’
inline std::list<Key> map_extract_keys(T const& a) {
note: template argument deduction/substitution failed:
note: couldn’t deduce template parameter ‘Key’
有什么办法允许自动扣除吗?
您的 map_type_of
概念无法帮助您解决更简单的概念
template<typename T>
concept is_map = std::ranges::range<T>
&& std::semiregular<typename T::key_type>
&& std::semiregular<typename T::mapped_type>;
template <typename T>
requires is_map<T>
inline std::list<typename T::key_type> map_extract_keys(T const& a) {
std::list<typename T::key_type> output;
for (auto const& [key, value] : a) {
output.push_back(key);
}
return output;
}
作为奖励,它允许 boost::bimap<...>::left_map
等
我想只要对您的代码进行最少的更改,您就可以做到:
template <template <typename, typename> class T, typename K, typename E>
requires map_type_of<T<K,E>, K, E>
inline auto map_extract_keys(T<K,E> const& a) {
std::list<K> output;
for (auto const& element : a) {
output.push_back(element.first);
}
return output;
}