【发布时间】:2016-03-28 18:05:39
【问题描述】:
在this answer我写了C++17代码:
cout << accumulate(cbegin(numbers), cend(numbers), decay_t<decltype(numbers[0])>{});
这收到了一些关于 C++ 类型关联性质的负面评论,我很遗憾地说我同意:(
decay_t<decltype(numbers[0])>{} 是一种非常复杂的获取方式:
numbers元素的零初始化类型
是否可以保持与 numbers' 元素类型的关联,但不能键入 30 个字符来获取它?
编辑:
我有很多答案涉及accumulate 或从numbers[0] 中提取类型的包装器。问题是他们需要读者导航到一个次要位置来阅读一个不比初始化代码decay_t<decltype(numbers[0])>{}复杂的解决方案。
我们必须做更多的唯一原因:decltype(numbers[0]) 是因为 array subscript operator 返回一个引用:
错误:将“int”类型的右值表达式无效转换为“int&”类型
有趣的是关于decltype的论点:
如果一个对象的名字被括号括起来,它被视为一个普通的左值表达式
但是,decltype((numbers[0])) 仍然只是对 numbers 元素的引用。因此,最终这些答案可能与我们可以简化此初始化一样接近:(
【问题讨论】:
-
如果你想要一个零,就写成这样:0。不需要在Ossa上堆Pelion。
-
@n.m.先生,这是绝对错误的。
0将accumulate的init定义为int。因此,例如,如果我们正在使用float numbers[],则这些值将被截断。例如,This example 应该输出 11.2,但如果我使用0,它将输出 10。 -
是的,你是对的。我忘了 std::accumulate 坏了...
-
@n.m.呵呵,我当然不会说那是坏的,而是非常有用。我经常使用
accumulate在lambda 中使用to_string从数字向量构造字符串。顺便说一句,如果类型不匹配,Visual Studio 2015 会触发 C4244 warning。因此,对于警告级别升高并正在关注它们的人,他们不会犯此错误。 -
好吧,一个让你写像
decay_t(decltype(..))这样的东西的 API 坏了。正常人应该不需要知道这些。在 C++11 中,我们可以将其封装在累加器中,但到目前为止,我们仍坚持使用 '03 API。
标签: c++ c++11 types decltype associated-types