是否有decltype的快捷方式

时间:2016-03-28 18:05:40

标签: c++ c++11 types decltype associated-types

this answer中,我编写了C ++ 17代码:

cout << accumulate(cbegin(numbers), cend(numbers), decay_t<decltype(numbers[0])>{});

此接收到关于C ++&#39的性质一些负面评论; S类型关联,这是我&#39; M悲伤地说,我同意:(

decay_t<decltype(numbers[0])>{}是一种非常复杂的获取方式:

  

numbers

元素的零初始化类型

是否可以保持与numbers&#39;的类型的关联?得到它的元素,但不是30个字符的类型?

修改

我有很多答案涉及accumulate的包装器或从numbers[0]中提取类型。问题是他们需要读者导航到辅助位置以读取与初始化代码decay_t<decltype(numbers[0])>{}同样复杂的解决方案。

我们必须做的更多的唯一原因是:decltype(numbers[0])是因为array subscript operator返回了引用:

  

错误:类型&#39; int&#39;的右值表达式的无效转换输入&#39; int&amp;&#39;

关于decltype的论点,这很有意思:

  

如果对象的名称带括号,则将其视为普通左值表达式

但是,decltype((numbers[0]))仍然只是对numbers元素的引用。所以最后这些答案可能就像我们简化这种初始化一样接近:(

3 个答案:

答案 0 :(得分:2)

虽然我总是选择按照@Barry编写辅助函数, 如果数字是标准容器,它将导出类型value_type,因此您可以节省一点复杂性:

cout << accumulate(cbegin(numbers), cend(numbers), decltype(numbers)::value_type());

更进一步,我们可以定义这个模板函数:

template<class Container, class ElementType = typename Container::value_type>
constexpr auto element_of(const Container&, ElementType v = 0)
{
    return v;
}

给了我们这个:

cout << accumulate(cbegin(numbers), cend(numbers), element_of(numbers, 0));

答案 1 :(得分:2)

个人偏好:我发现decay_tdecltypedeclval舞蹈非常烦人且难以阅读。

相反,我会通过类型特征value_t<It>使用额外的间接级别,并通过init = R{}进行零初始化

template<class It>
using value_t = typename std::iterator_traits<It>::value_type;

template<class It, class R = value_t<It>>
auto accumulate(It first, It last, R init = R{}) { /* as before */ }

答案 2 :(得分:1)

我认为你能做的最好的事情就是把它解决到某个地方:

template <class It, class R = std::decay_t<decltype(*std::declval<It>())>>
R accumulate(It first, It last, R init = 0) {
    return std::accumulate(first, last, init);
}

std::cout << accumulate(cbegin(numbers), cend(numbers));

或更一般地说:

template <class Range, class T =
        std::decay_t<decltype(*adl_begin(std::declval<Range&&>()))>>
T accumulate(Range&& range, T init = 0) {
    return std::accumulate(adl_begin(range), adl_end(range), init);
}

cout << accumulate(numbers);

其中adl_beginbegin()的一个版本,用于说明ADL。

当然,我们在技术上仍然拥有你之前想要避免的所有瑕疵......但至少现在你再也不用看它了?