3

这可能是与此问题相关的Templated Variables Bug With Lambdas in Visual Studio? 正如评论中提到的,似乎与优化器有关。


变量模板定义中的除法似乎在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 错误?这里有解决方法吗?

4

2 回答 2

2

应@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

于 2018-03-06T13:40:24.113 回答
0

我按原样测试了您的代码并得到了相同的结果。但是,我也单独进行了测试PIONE_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>);

这不会打印出正确的值,因为它会在将值分配给const T声明为的 LHS 变量之前进行除法DEG_TO_RAD

我不是 100% 确定,也没有引用我的话,但根据我自己的理解,我认为这可能是运算符优先顺序的问题。我认为在没有将 RHS 括在括号中的 Visual Studio 中,它没有正确执行除法运算,因此DEG_TO_RAD被设置为 0。

编辑

这是我的完整代码:当我尝试解决问题以在堆栈上回答时,我使用大约 80% 的标准库作为我的特定解决方案,因此我不会列出所有包含的内容,但我确实拥有大多数容器, I/O、数字、算法、内存、功能、计时、cmath、GLM 等。

在 Intel Quad Core Extreme 上的 Win 7 - 64 位家庭高级版上使用 Visual Studio 2017 v15.4.4。

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,我得到了相同的结果。这在您的机器 - 平台上可能会有所不同。

于 2018-03-05T21:40:25.937 回答