BOOST_CHECK编译失败运营商的LT;<自定义类型 [英] BOOST_CHECK fails to compile operator<< for custom types

查看:174
本文介绍了BOOST_CHECK编译失败运营商的LT;<自定义类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写这真是小巫见大巫类,这样很明显我的问题是:

I wrote this really trivial class so that it's clear what my problem is:

class A
{
public:
    int x;
    A(int y) {x=y;}
    bool operator==(const A &other) const {return x==other.x;}
};

现在,如果我定义了一个第一(1)和第二(1),这似乎自然,我认为BOOST_CHECK_EQUAL(第一,第二)应该通过。不过,我得到了50个错误试图做到这一点的时候,第一个听起来像:没有数学的运营商的LT;<在OSTR<< t内是升压code某处......其他的测试工作得很好,比较已知类型,甚至三分球,但有不同的东西,似乎与类对象的情况发生。

Now, if I define A first(1) and A second(1), it would seem natural to me that BOOST_CHECK_EQUAL(first, second) should pass. However, I got 50 errors when trying to do this, the first one sounds like: no math for operator << in ostr << t which is somewhere in the boost code... Other tests work just fine, comparing known types or even pointers, but there is something different that appears to happen with class objects.

推荐答案

有三种方式我已经确定要解决的问题运营商的LT;&LT;

There are three ways I have identified to solve the problem with operator<<.

第一种方式是提供一个运营商的LT;&LT; 你的类型。这是必要的,因为当 boost_check_equal 失败,它也通过调用运营商的LT记录故障;&LT; 的对象。查看详细编休息后看到这是如何实际完成。它的难度比它看起来。

The first way is to provide an operator<< for your type. This is needed because when boost_check_equal fails, it also logs the failure by calling operator<< with the objects. See the verbose addendum after the break to see how this is actually accomplished. It's harder than it might seem.

第二种方法是不行我刚才提到的记录。您可以通过 #definine 为此ING BOOST_TEST_DONT_PRINT_LOG_VALUE 。要禁用日志记录只是一个测试,你可能会环绕在测试这个问题的#define ,然后立即和#undef 它:

The second way is to not do the logging I just mentioned. You can do this by #definineing BOOST_TEST_DONT_PRINT_LOG_VALUE. To disable logging for just one test, you might surround the test in question with this #define, then immediately #undef it:

#define BOOST_TEST_DONT_PRINT_LOG_VALUE
BOOST_CHECK_EQUAL (first, second);
#undef BOOST_TEST_DONT_PRINT_LOG_VALUE

第三种方式是回避了一个运营商的LT的需要;&LT; 通过而不是一个项目相比另一个,但只是检查布尔与你的类型的作品:

The third way is to sidestep the need for an operator<< that works with your type by not comparing one item to another, but just checking a bool:

BOOST_CHECK (first == second);

选择您的preferred方法。

Select your preferred method.

我的preference是第一次,但实现这是令人惊讶的挑战。如果只是简单地定义一个运营商的LT;&LT; 在全球范围内,它不会工作。我认为,这样做的原因是因为名称解析的问题。一种流行的建议,以解决这个问题是把运营商的LT;&LT; STD 命名空间。这工作,在一些编译器的做法,至少,但由于标准禁止添加任何的 STD 命名空间,我不喜欢它。

My preference is the first, but implementing that is suprisingly challenging. If you simply define an operator<< in global scope, it won't work. I think the reason for this is because of a problem with name resolution. One popular suggestion to fix this is to put the operator<< in the std namespace. This works, at least in practice on some compilers, but I don't like it because the Standard prohibits adding anything to the std namespace.

更好的方法,我发现是实现一个自定义的 print_log_value 类模板特你的类型。 print_log_value 是由Boost.Test内部类模板useb实际调用正确的运营商的LT;&LT; 指定的类型。它代表一个运营商的LT;&LT; 来承担这个重任。专业 print_log_value 为您的自定义类型的正式升压[来源请求]的支持,并且正是如此完成的。

A better method I found is to implement a custom print_log_value class template specialization for your type. print_log_value is a class template useb by the Boost.Test internals to actually call the correct operator<< for the specified type. It delegates to an operator<< to do the heavy lifting. Specializing print_log_value for your custom types is officially supported by Boost [citation needed], and is accomplished thusly.

假设你的类型被称为时间戳(这是在我的code),先定义一个全球自由运营商的LT;&LT; 时间戳

Assuming your type is called Timestamp (it is in my code), first define a global free operator<< for Timestamp:

static inline std::ostream& operator<< (std::ostream& os, const Mdi::Timestamp& ts)
{
    os << "Timestamp";
    return os;
}   

...然后提供 print_log_value 专业化它,委托给运营商的LT;&LT; 只是你定义:

...and then provide the print_log_value specialization for it, delegating to the operator<< you just defined:

namespace boost { namespace test_tools {
template<>           
struct print_log_value<Mdi::Timestamp > {
void operator()( std::ostream& os,
    Mdi::Timestamp const& ts)
{
    ::operator<<(os,ts);
}
};                                                          
}}

这篇关于BOOST_CHECK编译失败运营商的LT;&LT;自定义类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆