变量模板中的除法在 Visual Studio 2017 中返回零
Division in Variable Template Returns Zero in Visual Studio 2017
这可能是与此问题相关的visual-studio-2017错误:Visual Studio 中 Lambda 的模板化变量错误?正如评论中提到的,似乎与优化器有关。
变量模板定义的划分似乎在Visual Studio 2017中存在错误。所以这个代码例如:
template <typename T>
const T PI = std::acos(static_cast<T>(-1));
template <typename T>
const T ONE_EIGHTY = 180;
template <typename T>
const T DEG_TO_RAD = PI<T> / ONE_EIGHTY<T>;
int main() {
cout << DEG_TO_RAD<float> << endl;
}
在 gcc 6.3 上,输出:
0.0174533
在Visual Studio 2017上,此输出:
0,0
我假设这是另一个Visual Studio错误?这里有解决方法吗?
应@JonathanMee的要求在此处发布解决方法,因为它也适用于他之前报告的类似问题。似乎与最新VS2017中的某种错误有关,该错误阻止模板自动激活并需要强制激活:
template <typename T>
const T PI = std::acos(static_cast<T>(-1));
template <typename T>
const T ONE_EIGHTY = 180;
template <typename T>
const T DEG_TO_RAD = PI<T> / ONE_EIGHTY<T>;
int main()
{
PI<float>; // <---- workaround
std::cout << DEG_TO_RAD<float> << std::endl;
}
这是向Microsoft提交的错误票:https://developercommunity.visualstudio.com/content/problem/207741/template-needs-to-be-force-instantiated-vs2017-bug.html
我按原样测试了您的代码并得到了相同的结果。但是,我也单独测试了PI
和ONE_EIGHTY
,他们在输出中给了我正确的结果。所以我考虑过它,出于某种原因,因为我不知道为什么Visual Studio这样做,这导致我认为它可能是一个错误,或者它可以留给compiler-implementation-design
但似乎它没有设置两个预定义常量的划分const T DEG_RAD
。
要在Visual Studio中解决此问题,它非常简单且容易被忽略;您所要做的就是用括号包装RHS表达式。
template<typename T>
const T DEG_TO_RAD = (PI<T> / ONE_EIGHT<T>);
这不会打印出正确的值,因为它会在将值分配给声明为DEG_TO_RAD
的 LHSconst T
变量之前进行除法。
我不是 100% 确定,也没有引用我的话,但根据我自己的理解,我认为这可能是运算符优先级顺序的问题。我认为在视觉工作室中没有将 RHS 包装在括号中,它没有正确执行除法操作,因此DEG_TO_RAD
设置为 0。
编辑
这是我的完整代码:当我尝试在堆栈上解决要回答的问题时,我将大约 80% 的标准库用于我的特定解决方案,所以我不会列出所有包含,但我确实拥有大多数容器、I/O、数字、算法、内存、函数、计时、cmath、GLM 等。
在 Win 7 上使用 Visual Studio 2017 v15.4.4 - 在英特尔四核至尊版上使用 64 位家庭高级版。
template <typename T>
const T PI = std::acos( static_cast<T>(-1) );
template <typename T>
const T ONE_EIGHTY = 180;
template <typename T>
const T DEG_TO_RAD = PI<T> / ONE_EIGHTY<T>;
int main() {
std::cout << PI<float> << std::endl;
std::cout << ONE_EIGHTY<float> std::endl;
std::cout << DEG_TO_RAD<float> std::endl;
_getch(); // include <conio.h> // just to stop the debugger from auto close
return 0;
}
输出:
3.14159
180
0
然后当我这样做时:
template <typename T>
const T PI = std::acos( static_cast<T>(-1) );
template <typename T>
const T ONE_EIGHTY = 180;
template <typename T>
const T DEG_TO_RAD = (PI<T> / ONE_EIGHTY<T>);
int main() {
std::cout << PI<float> << std::endl;
std::cout << ONE_EIGHTY<float> std::endl;
std::cout << DEG_TO_RAD<float> std::endl;
_getch(); // include <conio.h> // just to stop the debugger from auto close
return 0;
}
输出:
3.14159
180
0.0174533
我在所有 4 种模式下都尝试过这个:调试/发布 x86 和 x64,我得到了相同的结果。 这在您的计算机 - 平台上可能有所不同。
- 如何使用Visual Studio 2017在C++中为参数化对象数组使用唯一指针
- Visual Studio 2017循环自动向量化问题
- 有没有办法在远程设备上打开和编辑visual Studio 2017解决方案
- Visual Studio 2017 不允许我创建 C++ 专用模板
- Visual Studio 2017 停止工作,并在打开后显示许多控制台窗口
- 在Visual Studio 2017中使用recursive_directory_iterator
- 使用 CMake,Microsoft MPI 和 Visual Studio 2017 找不到 mpi.h
- Visual Studio 2017 中的 QtMetaObject 未解决的外部错误
- 智能感知不适用于Visual Studio 2017中的cmake项目
- 在Visual Studio 2017中创建的简单DLL不会在XP中加载
- Android NDK - 无法在 Visual Studio 2017 中调试
- Visual Studio 2017 - 调试和 Relese 配置,设置运行时库
- Visual Studio 2017 C++,不能使用 typeid() 获取信息对象,缺少指针?;
- 代码在Visual Studio 2017中不起作用,但在VS代码中工作
- 默认/样板代码在Visual Studio 2017中给我错误.E1574.虚幻.但构建成功了
- std::filesystem::create_directories Visual Studio 2017
- OpenCV 3 Visual Studio 2017 调试,调用堆栈没有.pdb文件
- Visual Studio 2017 15.5 Breaks C++ TypeDefs
- 在Visual Studio 2017中使用c ++组件构建python解决方案时出现问题
- 如何在Visual Studio 2017上将类方法设置为参数并将它们与lambda一起使用?