我写了这个非常琐碎的类,这样很清楚我的问题是:
class A
{
public:
int x;
A(int y) {x=y;}
bool operator==(const A &other) const {return x==other.x;}
};
现在,如果我定义了一个first(1)和一个second(1),那么BOOST_CHECK_EQUAL(first,second)应该通过我似乎很自然。但是,在尝试执行此操作时出现了50个错误,第一个听起来像是:运算符<
最佳答案
我已经确定了三种方法来解决operator<<
的问题。
第一种方法是为您的类型提供operator<<
。这是必需的,因为当boost_check_equal
失败时,它还会通过使用对象调用operator<<
来记录失败。休息后请参阅详细附录,以了解如何实际完成。这比看起来要难。
第二种方法是不执行我刚才提到的日志记录。您可以通过#definine
或BOOST_TEST_DONT_PRINT_LOG_VALUE
做到这一点。要仅对一个测试禁用日志记录,您可以使用#define
包围相关的测试,然后立即对其进行#undef
:
#define BOOST_TEST_DONT_PRINT_LOG_VALUE
BOOST_CHECK_EQUAL (first, second);
#undef BOOST_TEST_DONT_PRINT_LOG_VALUE
第三种方法是通过不将一项与另一项进行比较,而只是检查一个 bool 值,从而避免了需要与您的类型兼容的
operator<<
的需要:BOOST_CHECK (first == second);
选择您的首选方法。
我的首选是第一个,但实现起来却极具挑战性。如果仅在全局范围内定义
operator<<
,它将无法正常工作。我认为其原因是由于名称解析问题。解决此问题的一种流行建议是将operator<<
放入std
命名空间。这种方法至少在某些编译器上确实有效,但是我不喜欢它,因为标准禁止向std
namespace 添加任何内容。我发现一种更好的方法是为您的类型实现自定义
print_log_value
类模板特化。 print_log_value
是Boost.Test内部人员使用的类模板,它实际上为指定的类型调用正确的operator<<
。它委托(delegate)给operator<<
来完成繁重的工作。 Boost [需要引用]正式支持为您的自定义类型专门设置print_log_value
,并由此完成。假设您的类型称为
Timestamp
(在我的代码中),首先为operator<<
定义一个全局的免费Timestamp
:static inline std::ostream& operator<< (std::ostream& os, const Mdi::Timestamp& ts)
{
os << "Timestamp";
return os;
}
...然后为其提供
print_log_value
专门化,委托(delegate)给您刚定义的operator<<
:namespace boost { namespace test_tools {
template<>
struct print_log_value<Mdi::Timestamp > {
void operator()( std::ostream& os,
Mdi::Timestamp const& ts)
{
::operator<<(os,ts);
}
};
}}