首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iterator_traits SFINAE友好

iterator_traits SFINAE友好
EN

Stack Overflow用户
提问于 2018-03-13 15:41:46
回答 1查看 371关注 0票数 5

从cppreference读取节选

如果Iterator没有五个成员类型( difference_typevalue_typepointerreferenceiterator_category ),那么这个模板就没有这些名称的成员(std::iterator_traits是SFINAE友好的)。

我认为这意味着在迭代器本身中定义每个成员类型时都会定义它们。但是瞧,这实际上意味着,如果所有的五个都被定义了,那么它们就被定义了。

代码语言:javascript
复制
struct defined
{
    using difference_type = int;
    using value_type = int;
    using pointer = int*;
    using reference = int&;
    using iterator_category = std::input_iterator_tag;
};

struct undefined
{
    using value_type = int;
};

template<typename T>
using value_type = typename std::iterator_traits<T>::value_type;

void foo()
{
    using std::experimental::is_detected_v;
    static_assert(is_detected_v<value_type, defined>);
    static_assert(!is_detected_v<value_type, undefined>);
}

活着

为什么会这样呢?如果他们彼此独立的话,我会觉得他们更友好。例如,如果一个算法只需要在某个地方存储value_type,而不关心其他任何事情。

代码语言:javascript
复制
template<typename It>
auto amazingfy(It first, It last)
{
    typename std::iterator_traits<It>::value_type v;
    for(; first != last; first++)
        v += *first;
    return v;
}

它将无法在只定义value_type的迭代器上编译,但有趣的是,如果它是typename It::value_type v;,则会成功。

EN

回答 1

Stack Overflow用户

发布于 2018-03-13 16:19:06

可以从相应的提案N3844中获得一些见解。

事后看来,人们不时会认为,STL (以及由此产生的C++98)错误地将iterator_traits指定为一个由五种类型别名组成的包,而单个迭代器相关的特性将是一个更好的设计。即使是真的,这篇论文也不建议改变基本的捆绑设计,坚持要么全是要么全无的原则。

所以看起来,它只是试图非常谨慎地接近目前的情况,并作出最低限度的改变,以使特性SFINAE友好。有选择地加入该成员将导致半定义的特征,显然,这被认为是一个潜在的深远的结果。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49260285

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档