【问题标题】:Compiler error when using template specialization under Visual C++在 Visual C++ 下使用模板特化时出现编译器错误
【发布时间】:2016-06-05 14:47:04
【问题描述】:

我有以下 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 编译它时,我收到以下错误:

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

如果我不包含专业化foo&lt;float&gt;,程序编译得很好。该代码在 gcc 4.8.4 下也可以很好地编译包括专业化,这表明 Visual C++ 编译器存在问题。

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

【问题讨论】:

  • 我在 VS2015 上也有同样的错误,但它编译 here.
  • @Ben:好点子。我不知道这个网站。我不知道他们使用的是哪个编译器,但由于它编译成功,我假设它是 gcc。我很困惑为什么它用 gcc 编译但用 VC++ 失败。

标签: c++ templates visual-c++


【解决方案1】:

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

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

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

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

像往常一样调用它foo&lt;float&gt;();

【讨论】:

  • OP 观察到的错误消息很奇怪。知道为什么会出现 那个 特定的错误消息吗?
  • 我不得不认为这是 MSVS 解析函数时的错误。 Clang、g++和ICC都编译OP的问题没有问题。
  • @mindriot 我只能猜测编译器达到了基本模板,但不是“头脑清晰”,因此不能实际使用基本模板。为什么那个特定的消息并不重要。这是一个错误。
  • 我并不完全相信这个答案: 1. 禁止为模板特化指定默认参数这一事实意味着,函数模板中的默认参数也适用于其特化(请参阅@987654321 @) 2. 如果有歧义导致问题,我希望编译器会这样说明。 3. 所讨论的代码应该(不能)在编译器之间一致地编译。对我来说,这暗示了 VC++ 的一个更深层次的问题。
【解决方案2】:

我不使用“模板”关键字进行重载,而不是专门化,如下所示:

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

void foo(float value)
{
}

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

【讨论】:

  • 那不是专业化。这是超载。
  • 好吧,如果编译器不能正确进行特化,那么重载似乎是解决问题的好方法,这是原始问题的一部分。
  • 我同意,但是当我做特化时,我会不带“模板”关键字,像这样: 意味着当你做特化时,你使用流动的代码。我告诉你,这根本不是专业化,而是超载。您可以将其表述为 您可以添加一个采用 float 的重载,而不是专门化模板
猜你喜欢
  • 1970-01-01
  • 2019-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-30
  • 1970-01-01
  • 2013-11-11
  • 2011-07-21
相关资源
最近更新 更多