【发布时间】:2013-04-14 13:12:32
【问题描述】:
我有一个特征类,它通过推断成员函数的类型来定义“范围”(或容器、序列)的类型,如下所示:
template<class R>
struct range_type_traits
{
// "iterator": The type of the iterators of a range
using iterator = decltype(std::begin(std::declval<R>()));
// "value_type": The (non-reference) type of the values of a range
using value_type = typename std::remove_reference<decltype(*(std::declval<iterator>()))>::type;
};
我这样做的原因(而不是直接使用R 或std::iterator_traits 的子类型)是为了支持某些具有begin() 成员且不需要容器的模板库中的任何类型的容器定义了一些 value_type / iterator 类型。据我所知,std::iterator_traits 无法处理不使用对将其迭代器接口暴露给 STL 的容器的某种“键类型”,例如 std::map 所做的(例如:QMap<K,T> 具有 value_type = T . 您可以通过iterator::key() 访问密钥。)。
现在我想有条件地定义一个类型 key_type iif iterator 有一个函数 ::key() const 并采用它的返回类型,类似于我对 value_type 所做的事情。如果我只是将定义放在现有的特征类中,那么不支持它的容器编译会失败。
带有std::enable_if 的SFINAE 可以有条件地启用模板功能。如何有条件地扩展现有类/有条件地定义子类型?
类似这样的草图:
template<class R>
struct range_type_traits
{
// "iterator": The type of the iterators of a range
using iterator = decltype(std::begin(std::declval<R>()));
// "value_type": The (non-reference) type of the values of a range
using value_type = typename std::remove_reference<decltype(*(std::declval<iterator>()))>::type;
ENABLE_IF_COMPILATION_DOES_NOT_FAIL {
// "key_type": The (non-reference) type of the keys of an associative range not using pairs in its STL-interface
using key_type = typename std::remove_reference<decltype(std::declval<iterator>().key())>::type;
}
};
【问题讨论】:
标签: c++ templates c++11 sfinae typetraits