Dan*_*iel 11 c++ dictionary type-traits c++14
我有时会发现需要编写可以应用于对象容器的通用例程,或者这些容器的映射(即处理映射中的每个容器).一种方法是为地图类型编写单独的例程,但我认为有一个例程适用于两种类型的输入可能更自然,更简洁:
template <typename T>
auto foo(const T& items)
{
return foo(items, /* tag dispatch to map or non-map */);
}
Run Code Online (Sandbox Code Playgroud)
什么是安全,干净的方式来执行此标签发送?
Jon*_*ely 13
现有的答案测试非常具体的属性std::map,要么是它的特殊化std::map(对于std::unordered_map具有相同接口的非标准类型是假的std::map),要么测试它value_type是否正确std::pair<const key_type, mapped_type>(对于multimap和unordered_map,但对于具有类似接口的非标准类型,则为false).
这只测试它提供key_type和mapped_type成员,并且可以访问operator[],所以不要说std::multimap是mappish:
#include <type_traits>
namespace detail {
// Needed for some older versions of GCC
template<typename...>
struct voider { using type = void; };
// std::void_t will be part of C++17, but until then define it ourselves:
template<typename... T>
using void_t = typename voider<T...>::type;
template<typename T, typename U = void>
struct is_mappish_impl : std::false_type { };
template<typename T>
struct is_mappish_impl<T, void_t<typename T::key_type,
typename T::mapped_type,
decltype(std::declval<T&>()[std::declval<const typename T::key_type&>()])>>
: std::true_type { };
}
template<typename T>
struct is_mappish : detail::is_mappish_impl<T>::type { };
Run Code Online (Sandbox Code Playgroud)
因为is_mappish有一个"基本特征" true_type或者false_type你可以像这样发送:
template <typename T>
auto foo(const T& items, true_type)
{
// here be maps
}
template <typename T>
auto foo(const T& items, false_type)
{
// map-free zone
}
template <typename T>
auto foo(const T& items)
{
return foo(items, is_mappish<T>{});
}
Run Code Online (Sandbox Code Playgroud)
或者你可以完全避免调度,只是重载foo地图和非地图:
template <typename T,
std::enable_if_t<is_mappish<T>{}, int> = 0>
auto foo(const T& items)
{
// here be maps
}
template <typename T,
std::enable_if_t<!is_mappish<T>{}, int> = 0>
auto foo(const T& items)
{
// map-free zone
}
Run Code Online (Sandbox Code Playgroud)
Dav*_*aim 10
这对我有用,但未经100%测试:
template <class T>
struct isMap {
static constexpr bool value = false;
};
template<class Key,class Value>
struct isMap<std::map<Key,Value>> {
static constexpr bool value = true;
};
int main() {
constexpr bool b1 = isMap<int>::value; //false
constexpr bool b2 = isMap<std::vector<int>>::value; //false
constexpr bool b3 = isMap<std::map<int,std::string>>::value; //true
constexpr bool b4 = isMap<std::future<int>>::value; //false
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2279 次 |
| 最近记录: |