【问题标题】:Why do I get an "illegal token" compile-time error with this piece of C++ code?为什么这段 C++ 代码会出现“非法令牌”编译时错误?
【发布时间】:2012-05-07 18:16:51
【问题描述】:

在我的应用程序中(在 Visual C++ 2010 下编译),我的头文件中有这样的代码:

// example.h
#pragma once

#include <limits>

namespace myspace
{

// A generic equality test
template<typename T> inline bool equal(
    const T &v1, 
    const T &v2, 
    const T &eps = std::numeric_limits<T>::epsilon())
{
    return (v1 == v2);
}

// Template specialization for floating-point numbers
template<> bool equal<float>(
    const float &v1, 
    const float &v2, 
    const float &eps);

// A generic equality test for finite-precision real number representations (with epsilon)
template<typename T> inline bool realEqual(
    const T &p, 
    const T &q, 
    const T &eps = std::numeric_limits<T>::epsilon())
{
    return (fabs(p - q) < eps);
}

} // namespace myspace

...以及 .cpp 文件中的一些代码:

// example.cpp
#include "example.h"

using namespace std;
using namespace myspace;

// equal-macro specialization that calls the appropriate equality test function for real numbers
template<> bool myspace::equal<float>(
    const float &v1, 
    const float &v2, 
    const float &eps)
{
    return (realEqual(v1, v2, eps));
}

int _tmain(int argc, _TCHAR* argv[])
{
    float a,b;
    bool x = realEqual(a,b); // OK
    bool x = equal(a,b); // compile error
    return 0;
}

这编译失败,给我:

----- 构建开始:项目:测试,配置:调试 Win32 ------
测试.cpp
c:\users\ninja\documents\visual studio 2010\projects\test\test\test.h(10): 错误 C2589: '::' : '::' 右侧的非法令牌
c:\users\ninja\documents\visual studio 2010\projects\test\test\test.h(10):错误 C2059:语法错误:'::'
========== 构建:0 成功,1 失败,0 最新,0 跳过 ==========

违规行是定义了 equal() 函数的“eps”参数默认值的行。

谷歌搜索显示人们在 numeric_limits 中的其他函数(即 min() 和 max())中也遇到过类似的“非法令牌”错误,但这是由于特定于 Windows 的 c++ 标准库头文件中存在一些#define ,由于某些遗留原因,它定义了“min”和“max”。没有提到 epsilon(),我对为什么我在这里遇到错误感到非常困惑。无论如何,将函数名称从“equal”更改为“smartEqual”之类的名称仍然会出现相同的错误,因此名称显然不是问题。是什么?

谢谢!

【问题讨论】:

  • 如果去掉它编译的默认参数?
  • 作为一个数据点,Comeau 在线编译器 (comeaucomputing.com/tryitout) 如果包含 cmath 标头并在第二个 x 之前去掉无关的 bool (好吧,并适当更改_tmain的签名并将其全部放在一个文件中...)
  • 作为另一个数据点,Lion 上的 g++ 也可以很好地编译该最小修改版本。
  • @Seth:是的,删除默认参数会使其编译,但我真的很想要那个值,因为大多数时候它是可取的。在我看来,equal 和 realEqual 几乎是一回事,那么为什么一个有效而另一个无效?
  • @Stuart:我在VS2010下添加了,没有变化。

标签: c++ visual-studio compiler-errors numeric-limits


【解决方案1】:

看起来是由 Visual Studio 中的这个错误引起的:

https://connect.microsoft.com/VisualStudio/feedback/details/583081/

参见此处:

template function specialization default argument

【讨论】:

  • 谢谢!我通过创建一个额外的模板函数 getEpsilon() { return numeric_limits::epsilon(); 解决了这个问题。 } 并使用它初始化默认参数。
  • “鉴于此,我们计划在下一个版本中不修复此错误,以解决没有解决方法的更严重问题。”啊,微软。为什么不同时解决这两个问题并推迟一天发布?
  • @Seth:可能是因为:“不幸的是,修复我们编译器的这个区域成本高昂,容易引入更严重的问题,并且可能导致现有(格式错误但可操作)代码出现问题。”。我不羡慕那些背负着破旧代码行李的家伙。也就是说,在某种程度上很高兴知道不是我搞砸了一次。 ;)
  • @neuviemeporte 这不是(好的)借口。做对并修复您的代码 Microsoft!不过我确实对他们有感觉,他们是一家庞大的公司,驾驭这么大的船并不容易。
  • 现在我遇到了另一个错误,无法使用该函数两次... :/ 见stackoverflow.com/questions/10343741/…
猜你喜欢
  • 2011-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-28
  • 1970-01-01
  • 2010-10-19
相关资源
最近更新 更多