2

我正在使用 Boost 1.46 和 Turtle lib 1.2.4 和 Visual Studio Express 2013 的编译器。我有以下类来模拟:

struct IPredicate
{
    virtual ~IPredicate() {}

    virtual bool operator()(float value) = 0;
};

当我用 MOCK_NON_CONST_METHOD 模拟 operator() 时:

MOCK_BASE_CLASS(MockPredicate, IPredicate)
{
    MOCK_NON_CONST_METHOD(operator(), 1, bool(float), id)
};

我遇到了一堆编译器错误,例如语法错误'operator'等等。但是当我用 MOCK_NON_CONST_METHOD_EXT 模拟它时:

MOCK_BASE_CLASS(MockPredicate, IPredicate)
{
    MOCK_NON_CONST_METHOD_EXT(operator(), 1, bool(float), id)
};

一切都很好,完美无缺!根据http://turtle.sourceforge.net/turtle/reference.html带有 EXT 后缀的 MOCKS 用于“不支持可变参数宏的编译器”,但我使用的那个有支持(用这些例子检查:http:// /msdn.microsoft.com/en-us/library/ms177415.aspx)。文档的其余部分对此案例并不十分清楚。

有人能解释一下这里是怎么回事吗?为什么我不使用 EXT 后缀 MOCK 版本时会出现错误?

4

2 回答 2

2

坚持者的回答是,通常不能保证可变参数宏,因为可变参数宏在 C++03 中是非标准的(但在 C++11 中是标准的)。因此,如果您有一种方法可以避免使用可变参数宏,那么您绝对应该使用它来代替带有可变参数宏的方法。

实际上,虽然turtle 库很可能没有经过 msc 的广泛测试,并且只是依赖于宏的非标准 gcc 扩展之一。扩展在 Variadic Macros http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html页面上讨论。具体来说,对于所有符合 C99 的编译器来说,turtle 库都是可移植的,只能__VA_ARGS__使用。

使用宏,当您在根案例之后 - 使用 msc 的 /P 开关(Preprocess to a File)生成一个.i扩展了预处理器指令的文件,您可以在其中检查它对什么不满意。

更新。当我完成这个漫长的故事时,我决定快速下载海龟并检查宏是如何定义的。正如我所做的那样,我发现这只是一个文档未维护的可悲案例。在库上运行 grep 包括我根本找不到MOCK_NON_CONST_METHOD定义。这就是您收到语法错误的原因。避免使用宏的另一个原因 - C++ 错误消息的清晰性和完整性。

于 2014-01-31T10:43:37.530 回答
1

(我是乌龟的作者)

1.2.4 发生的事情是出于某种原因,我没有真正调查提供的代码实际上是 1.2.1 以及 1.2.4 文档。由于没有人抱怨直接在 sourceforge 上开票,我直到很长一段时间才注意到(我所有使用 turtle 的个人和公司项目都与最新的源代码不断集成)。

无论如何,我刚刚测试了您的代码,它可以使用 MSVC 2013、turtle 1.2.6 和 boost 1.55 进行编译。如果您当时还没有这样做,您应该考虑升级。

于 2015-04-12T19:22:22.910 回答