在 Visual C++ 下使用模板专用化时编译器错误

Compiler error when using template specialization under Visual C++

本文关键字:专用 编译器 错误 C++ Visual      更新时间:2023-10-16

我有以下 cpp 代码:

#include <iostream>
#include <limits>
// C2589 when compiling with specialization, fine when compiling without
template<typename T>
void foo(T value = std::numeric_limits<T>::infinity() )
{
}
// this specialization causes compiler error C2589 above
template<>
void foo<float>( float value )
{
}
int main()
{
    foo<float>();
    return 0;
}

当我尝试使用Visual Studio 2013编译它时,我收到以下错误:

..check2main.cpp(5) : error C2589: '::' : illegal token on right side of '::'
..check2main.cpp(5) : error C2059: syntax error : '::'

如果我不包括专业化foo<float>,该程序编译得很好。代码也可以很好地编译,包括 gcc 4.8.4 下的专用化,这表明 Visual C++ 编译器存在一些问题。

代码是否正确,是否应该编译?是否有针对视觉C++的解决方法?

通过在调用foo<float>();时省略参数,您将编译器置于难题中。编译器同时得出结论,专用函数是正确的选择,因为你明确地说<float>,而不是那个,因为没有参数。然后编译器到达通用版本,但它不能,因为有一个专门的版本。即使是HAL9000也无法弄清楚那个,除非它是用 gcc 构建的。VC++ 错误地处理这种情况。可能是一个错误,而不是"设计使然"。

Visual C++的解决方法是使用重载:

template<typename T>
void foo(T value)
{
}
template<typename T>
void foo()
{
    foo(std::numeric_limits<T>::infinity());
}

并像往常一样称呼它foo<float>();

我没有使用

专业化,而是在没有"模板"关键字的情况下进行重载,如下所示:

template<typename T>
void foo(T value)
{
}
void foo(float value)
{
}

我在gcc和Visual Studio 2012中使用它们。