- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
这是一个 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/
我需要两个关于整数的特征。 第一个类似于 std::is_integral (或 boost::is_integral ),但可用于用户定义的类型(例如包装 int 的类,比如 int_wrapper
我不熟悉 cpp 中的模板魔术。在阅读了 link 中“TemplateRex”所说的内容后,我对 std::is_intergral 的工作方式感到困惑。 template struct is_in
我创建了一个类型验证器来检查给定的参数是否是数字。 template struct is_numeric : std::integral_constant || std::is_floatin
我正在尝试实现一个自由运算符函数,以便将任意数据类型的值流式传输到某个容器类 (DataVector) 中。 我为基本数据类型做了一个模板,并为我的项目中使用的复杂数据类型做了一些专门化(示例仅涵
假设我们有两个函数: //(1) template::value & ! is_integral_literal::value>::type > void foo(T) { } 和 //(2) tem
我正在尝试返回 int64_t如果 std::is_integral<>::value是真的。 否则,我想调用 to_int64t()在物体上。 我在下面的尝试失败了,因为不允许函数模板的部分特化。
像std::is_pointer和std::is_integral,如何实现std::is_cstring_pointer? 我想检查指针是否是一个c类型的字符串指针,可以吗? 如何实现这个目标? 最
我想根据给定的类型为 std::uniform_*_distribution 创建一个特征。例如: distribution_traits::type int_dist; 我尝试了以下方法,但没有一种
我一直在研究标签分派(dispatch),下面的代码完全符合我的预期: #include #include void impl(std::true_type) { std::cout void
如果我需要满足 std::is_unsigned 和 std::is_integral 的类型,我是必须同时检查还是只检查 std::is_unsigned? 最佳答案 cppreference 有此
is_integral和 is_integer似乎以同样的方式回答同样的事情。 从相关文档页面的链接来看,is_integral 似乎缺少以下类型的特化 signed char unsig
在 C++ 类型特征中std::is_integral::value即使 T 是 bool 也返回真,这根据其描述是正确的。 但是如果 bool 是与其他整数类型不同的类型,为什么在这种情况下将其视为
我有一个函数,但我想将它分成两个函数,一个用于返回有符号整数,一个用于返回无符号整数。看起来像 std::is_signed不是严格意义上的整数,所以我想我是否可以对类似 std::is_integr
这是一个 C++17 的简短程序: #include #include using namespace std::string_literals; int main() { std::st
C++11 提供了两种类型特征模板类:std::is_integer和 std::is_integral .但是,我无法分辨它们之间的区别。 什么类型,比如说T,可以做成std::is_integer
我正在尝试在 oder 中使用 boost 来计算阶乘。我不知道为什么,但 VS2013 显示编译错误。 有人有什么想法吗? int nLgCombi = 12; std::vector NbrT
我是一名优秀的程序员,十分优秀!