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

C++ 在Visual C+;下使用模板专门化时出现编译器错误+;,c++,templates,visual-c++,C++,Templates,Visual C++,我有以下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 specializatio

我有以下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;
}
如果我不包括专门化
foo
,程序编译得很好。代码还编译了Grime<强>,包括GCC 4.84下的专业化< /强>,这表明Visual C++编译器存在一些问题。
代码是否正确,是否应该编译?在调用<代码>()时省略参数,VisualC++(?)/< > > P>有一个解决方案吗?<代码>将编译器置于一个难题中。编译器同时得出结论,选择专用函数是正确的,因为您明确地说
,而不是因为没有参数。然后,编译器将访问通用版本,但它无法访问,因为有一个专用版本。即使是HAL9000也无法理解这一点,除非它是用gcc构建的。VC++错误地处理了这种情况。可能是一个bug,而不是“出于设计”

VisualC++的工作环境是使用重载:

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

template<typename T>
void foo()
{
    foo(std::numeric_limits<T>::infinity());
}
模板
无效foo(T值)
{
}
模板
void foo()
{
foo(std::numeric_limits::infinity());
}

并像往常一样调用它
foo()

我不进行专门化,而是在没有“template”关键字的情况下进行重载,如下所示:

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

void foo(float value)
{
}
模板
无效foo(T值)
{
}
void foo(浮点值)
{
}

我在gcc和Visual Studio 2012中使用了这些工具。

我在VS2015上也有同样的错误,但它可以编译。@Ben:说得好。我不知道这个网站。我不知道他们使用哪种编译器,但由于它编译成功,我假设它是gcc。这让我困惑,为什么它用gcc编译,但用VC++编译失败。不过OP观察到的错误消息很奇怪。你知道为什么会出现这样的错误消息吗?我不得不认为这是MSV解析函数时的一个错误。Clang、g++和ICC都能毫无问题地编译OP的问题。@Mindrio我只能猜测编译器达到了基本模板,但没有“头脑清醒”,因此不能实际使用基本模板。为什么会有这样的信息并不重要。这是一个错误。我不完全相信这个答案:1。禁止为模板专门化指定默认参数这一事实意味着,函数模板中的默认参数也适用于其专门化(请参阅)2。如果存在导致问题的歧义,我希望编译器会这样说。3.讨论的代码应该(未能)跨编译器一致编译。对我来说,这暗示了VC++的一个更深层次的问题,那不是专门化。这是重载。如果编译器不能正确地进行专门化,那么重载似乎是解决问题的一个好方法,这是原始问题的一部分。我同意,但当我进行专门化时,我不使用“模板”关键字,比如:这意味着当你进行专门化时,你会使用流动的代码。我告诉你,这根本不是专门化,而是重载。你可以这样说,而不是专门化模板,你只需添加一个重载,它采用一个
float
template<typename T>
void foo(T value)
{
}

void foo(float value)
{
}