c++ - constexp 函数中的 C++ Wconversion 警告,但模板中没有
问题描述
我的问题是为什么以下代码会生成警告只为constexpr
函数生成警告而不为模板生成警告?
我确实了解警告的含义以及如何摆脱它们。我不明白为什么编译器不会为constexpr
成员ToDouble
和以下ToSquare
内容产生警告struct Test
?
#include <iostream>
template <typename T, T value>
struct Test {
static constexpr double ToDouble = value;
static constexpr T ToSquare = value * value;
};
template <typename T>
constexpr double ToDouble(T value) {
return value;
}
template <typename T>
constexpr T ToSquare(T value) {
return value * value;
}
int main() {
std::cout << Test<long, 1>::ToDouble << std::endl;
std::cout << ToDouble(static_cast<long>(1)) << std::endl;
std::cout << Test<char, 1>::ToSquare << std::endl;
std::cout << ToSquare(static_cast<char>(1)) << std::endl;
}
$ g++ -Wconversion -std=c++11 a.cc
a.cc: In instantiation of ‘constexpr double ToDouble(T) [with T = long int]’:
a.cc:22:45: required from here
a.cc:12:10: warning: conversion to ‘double’ from ‘long int’ may alter its value [-Wconversion]
return value;
^~~~~
a.cc: In instantiation of ‘constexpr T ToSquare(T) [with T = char]’:
a.cc:25:45: required from here
a.cc:17:16: warning: conversion to ‘char’ from ‘int’ may alter its value [-Wconversion]
return value * value;
解决方案
模板生成一个类型。在该类型的每个实例中,该值value
都是一个编译时间常数。它可以检查精度损失。
这种constexpr
情况下,模板函数的生成函数没有这个属性。不保证该参数value
是编译时间常数。虽然您仅在它是编译时间常量的上下文中使用它,但警告不会检查每个调用上下文。
可能你误会了constexpr
;在函数上,它声明该函数可以在编译时进行评估,而不是必须是.
推荐阅读
- excel - VBA 记录集不返回所有数据
- java - 环境变量 JAVA_HOME 未指向 Android Studio 中的有效 JVM
- machine-learning - 是否有仅为人体检测创建的预训练权重?
- python - 如何在两个值之间使用 CV2 标准化图像?
- flutter - 扑腾解析平台中的订阅.on('open')等效项
- google-cloud-platform - Terraform 不应用我的分支的更改
- python - 仅列出 OneToOneField Django 中的特定值
- java - 更改条件内的数据类型
- gimp - 如何使用 python-fu 重命名图层
- java - Springboot应用程序启动后出现错误