变量模板中的除法 Returns 零 Visual Studio 2017
Division in Variable Template Returns Zero in Visual Studio 2017
这可能是 visual-studio-2017 bug related to this question: And as 似乎与优化器有关。
一个variable template定义中的划分似乎在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;
}
On gcc 6.3 这输出:
0.0174533
2017 年 Visual Studio 输出:
0.0
我假设这是另一个 Visual Studio 错误?这里有解决方法吗?
我按原样测试了您的代码并得到了相同的结果。然而,我也单独测试了 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
.
的 LHS const T
变量之前进行除法运算
我不是 100% 确定,也不要在这方面引用我的话,但根据我自己的理解,我认为这可能是运算符优先顺序的问题。我认为在 visual studio 中没有将 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 种模式下都试过了:Debug/Release x86 和 x64,我得到了相同的结果。
这在您的机器平台上可能有所不同。
应@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
这可能是 visual-studio-2017 bug related to this question:
一个variable template定义中的划分似乎在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;
}
On gcc 6.3 这输出:
0.0174533
2017 年 Visual Studio 输出:
0.0
我假设这是另一个 Visual Studio 错误?这里有解决方法吗?
我按原样测试了您的代码并得到了相同的结果。然而,我也单独测试了 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
.
const T
变量之前进行除法运算
我不是 100% 确定,也不要在这方面引用我的话,但根据我自己的理解,我认为这可能是运算符优先顺序的问题。我认为在 visual studio 中没有将 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 种模式下都试过了:Debug/Release x86 和 x64,我得到了相同的结果。 这在您的机器平台上可能有所不同。
应@JonathanMee 的要求在此发布解决方法,因为它也
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