【问题标题】:Why in this case decltype behavior is different from normal expression with libstdc++?为什么在这种情况下 decltype 行为与使用 libstdc++ 的正常表达式不同?
【发布时间】:2018-01-05 08:23:50
【问题描述】:

我发现decltype 内部的表达式处理成功,而decltype 外部的相同表达式给出错误:see on Godbolt

我正在检查给定类型 (operator <<) 是否存在输出到流的过载 - 通过使用 decltype 和类型特征。但是对于来自 GCC decltype 的 libstdc++,即使在没有这种重载的情况下也会返回正确的类型。

我用 libc++ 尝试了 Clang - 没有这样的问题。试过 GCC 7.1 - 没问题。但是,如果我尝试使用 GCC

基本上:

class Foo {};

...

decltype(std::declval<std::ostringstream>() << std::declval<Foo>()) // gives std::ostringstream&

...

Foo foo;
std::ostringstream out;
out << foo; // gives an error (as it should, there is no overload for Foo)

那么,为什么会这样,libstdc++ 出了什么问题?

【问题讨论】:

  • 每种情况下使用哪个 C++ 版本? (如果不强制使用 --std= 标志,默认使用哪个版本?),可能响应不同,因为每个编译器默认使用不同版本的 C++。
  • clanggcc 在这个例子中给出了相反的结果。所以这似乎是一个编译器错误?
  • 正如您在 Godbolt 上看到的,我在所有情况下都使用 -std=c++14 标志。

标签: c++ c++11 c++14 libstdc++


【解决方案1】:
std::declval<std::ostringstream&>() << std::declval<T const &>()
//                             ^                     ^^^^^^^^

价值类别很重要。您正在测试将const T 左值流式传输到ostringstream 左值的能力。

在您的原始代码中,&lt;&lt; 解析为右值流的until-recently-unconstrained &lt;&lt; 重载。没有约束,表达式总是格式良好的。

【讨论】:

  • 您能否详细说明“直到最近不受约束的过载”?它在 libstdc++ 中是如何不受约束的(而在 libc++ 中是受约束的)?
  • 谢谢!奇怪的是,它在 libc++ 状态中没有被标记为完成:libcxx.llvm.org/cxx1z_status.html(但它至少从 clang 3.4 开始工作)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-06
  • 1970-01-01
  • 1970-01-01
  • 2017-01-07
  • 1970-01-01
  • 2014-08-22
  • 2021-07-13
相关资源
最近更新 更多