【问题标题】:Conditionally choose a type with decltype() and the ternary operator有条件地选择带有 decltype() 和三元运算符的类型
【发布时间】:2019-12-22 15:08:31
【问题描述】:

我有一个文件a.cpp

#include <bits/stdc++.h>

using namespace std;

int main(){
    int a=5;
    double b=4.3;
    decltype(a>b?a:b) n;
    cout << typeid(n).name();   
}

上述代码的输出是 d 但我希望它是 i 因为“a”大于“b”

我正在尝试了解 decltype。你能告诉我这里缺少什么吗?

我使用的是 gcc 版本 6.3.0 (MinGW.org GCC-6.3.0-1)。

【问题讨论】:

  • 无论哪个更大,表达式的类型都是双精度的。
  • C++ 是一种静态类型语言。
  • @PrashantKumarNirmal 如果使用相同类型的参数调用该函数并使用其返回值(这将是对超出其生命周期的参数之一的引用),该函数会导致未定义的行为。你不应该使用它。您需要删除尾随返回类型以使其行为正确。在任何一种情况下,它都会返回一个编译时固定类型,由所描述的规则确定,例如here.
  • 顺便说一句,关于@walnut 所描述的事情,这是真的,这也是我(和许多其他人)觉得C++ 对普通用户完全失控的原因。让无声但又很关键的错误真的不应该那么简单。
  • @LightnessRacesBY-SA3.0 Clang 至少给出了一个warning。令人惊讶的是,GCC 没有。

标签: c++ c++11 decltype


【解决方案1】:

C++ 是一种静态类型语言。

也就是说,事物的类型不能依赖于运行时标准。

因此,表达式a&gt;b?a:b 将始终计算为相同类型的值。这是条件运算符规则的一部分。

在这种情况下,“相互兼容的类型”(我已经编造了这个术语)是double,所以你总是会得到一个double(参见规则here)。

如果a 赢得条件,它会从int 转换为double,除非在decltype 中,您的代码是“未评估的上下文”(因为运行时没有任何东西可能影响结果),所以条件甚至不执行,只计算可能的结果类型,从条件运算符的参数类型。如果有多种可能的结果类型,那么代码将不明确,您的程序将无法编译。

您可以使用 std::variant 之类的魔法来实现此行为,但请考虑您是否真的需要/想要它。

【讨论】:

  • template&lt;class T1, class T2&gt; auto max(T1 a, T2 b) -&gt; decltype(a&gt;b?a:b) { return a&gt;b?a:b;} 那么这段代码是如何工作的呢?
  • @PrashantKumarNirmal 它没有。
猜你喜欢
  • 2017-11-09
  • 2017-01-27
  • 2019-07-21
  • 2017-08-28
  • 2012-01-22
  • 2014-09-15
  • 2014-09-07
相关资源
最近更新 更多