使用带有decltype的std :: any_cast…为什么这段代码会抛出错误的any_cast?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用带有decltype的std :: any_cast…为什么这段代码会抛出错误的any_cast?相关的知识,希望对你有一定的参考价值。

我正在将std :: any_cast与decltype结合使用:

#include <any>
#include <iostream>

auto bar(char c) { return (c == 'i' ? 42 : true);}

auto foo(char c) { return (c == 'i' ? 42 : (c == 'd' ? 4.4 : true));}

int main() {
  std::any MyInt = 123456789;
  std::cout << std::any_cast<decltype(bar('i'))>(MyInt)
            << std::endl;  // works just fine
  std::cout << std::any_cast<decltype(foo('i'))>(MyInt)
            << std::endl;  // throws bad any_cast
}

您可以see online at Godbolt使用bar的转换工作正常,而使用foo的版本会抛出错误的any_cast。为什么会这样,如何解决foo版本?

我很清楚这个事实,我可以只使用std::any_cast<int>(MyInt)。但是我真的很想使用decltype和函数的foo版本。谢谢!

答案

三元表达式的两个操作数必须具有相同的类型。在类似[]的表达式中

c == 'i' ? 42 : true; 

返回类型为int,因为true可以转换为int。因此,bar返回int

根据相同的逻辑,foo返回double。因此,当您将any_castint设置为double时,它将失败。

您可以通过以下方式进行检查

static_assert(std::is_same_v<decltype(bar('i')),int>);
static_assert(std::is_same_v<decltype(foo('i')),double>);
另一答案

函数的返回类型独立于传递给函数本身的任何实例。您只能在编译时使用类似以下内容的方式进行与数据相关的类型查找:

以上是关于使用带有decltype的std :: any_cast…为什么这段代码会抛出错误的any_cast?的主要内容,如果未能解决你的问题,请参考以下文章

std::declval() 在 GCC 中触发带有警告的断言错误

decltype 是如何工作的?

为啥类不能从 decltype 的结果继承?

std::common_type 应该使用 std::decay 吗?

指向引用的指针获取器

为啥 std::bind 不能作为参数包的参数?