gpt4 book ai didi

c++ - 为什么 is_integral 认为 std::string 是整数?

转载 作者:太空狗 更新时间:2023-10-29 20:51:06 26 4
gpt4 key购买 nike

这是一个 C++17 的简短程序:

#include <iostream>
#include <string>

using namespace std::string_literals;

int main() {
std::string n = "asdf"s;

if constexpr (std::is_integral<decltype(n)>::value) {
std::cout << static_cast<int>(n) << std::endl;
} else {
std::cout << n << std::endl;
}
return 0;
}

但它无法编译,因为很明显,is_integral认为 std::string是积分:

g++ -o main.o -c -std=c++17 -O2 -pipe -fPIC -fno-plt -fstack-protector-strong -Wall -Wshadow -pedantic -Wno-parentheses -Wfatal-errors main.cpp
main.cpp: In function 'int main()':
main.cpp:10:40: error: invalid static_cast from type 'std::__cxx11::string' {aka 'std::__cxx11::basic_string<char>'} to type 'int'
std::cout << static_cast<int>(n) << std::endl;
^
compilation terminated due to -Wfatal-errors.

我如何在编译时区分可以转换为 int 的内容? ,还有什么不能?

这个问题与“为什么 if constexpr 不使这个核心常量表达式错误消失?”不同,因为它与模板无关(即使正确用法,对于这种情况,可能在一个模板)。问题本身也是不同的,即使主题是相关的。

这个问题与“Constexpr if with non-template types”不同,因为它专门针对 std::is_integral 的行为。 .

最佳答案

C++ 不允许您使用格式错误的代码。让我们举一个简单的例子:

int i = 0;
if constexpr (sizeof(int) > 98) { // never happen
i = "a string";
}

编译器很容易看出 is constexpr 的内容永远不会有效。很像 static_assert(false) 永远是一个硬错误。这是因为即使从未在 constexpr if 中调用代码,内容也会使用 ODR。

那你问为什么模板是一个特例?为什么禁用模板中的无效代码有效?事实是没有特殊情况。将我上面的代码放入模板中:

[](auto) { // this is a template
int i = 0;
if constexpr (sizeof(int) > 98) { // never happen
i = "a string"; // same error
}
}

这是因为编译器仍然可以证明这段代码对于任何模板实例化都是无效的。

但是,如果您在 constexpr if 中使用依赖指令,编译器将很难“证明”不会有任何模板实例化使其有效。看看这个修改后的例子:

[](auto a) { // this is a template
if constexpr (sizeof(a) > 98) { // maybe happen
a = "a string"; // no error?
}
}

在这里,编译器无法证明 a 的类型永远不会大于 98,也无法证明您永远无法为其分配字符串文字。有可能在代码中的任何地方添加一个可能满足此表达式的新类型。这与使用模板类的成员函数时的行为类似:如果该函数在给定模板参数的情况下不会产生有效的实例化,那么只要您不使用该函数就没有问题。

关于c++ - 为什么 is_integral 认为 std::string 是整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51823836/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com