我有一个班级:
class foo {
private:
std::string data;
public:
foo &append(const char* str, size_t n) { data.append(str,n); }
// for debug output
template <typename T>
friend T& operator<< (T &out, foo const &f);
// some other stuff
};
template <typename T>
T& operator<< (T &out, foo const &f) {
return out << f.data;
}
我希望这适用于提供<<
运算符的任何类。
这适用于std::cout
,如:
std::cout << fooObject;
但以下失败:
BOOST_AUTO_TEST_CASE( foo_append_and_output_operator )
{
// fooObject is accessable here
const char* str = "hello";
fooObject.append(str, strlen(str));
output_test_stream output;
output << fooObject;
BOOST_CHECK( output.is_equal(str) );
}
g++
告诉我:
In function ‘T& operator<<(T&, const foo&)
[with T = boost::test_tools::output_test_stream]’:
error: invalid initialization of reference of type
‘boost::test_tools::output_test_stream&’ from expression of type
‘std::basic_ostream<char, std::char_traits<char> >’
发生了什么事?
我在Ubuntu 8.04上使用Boost 1.34.1。
答案 0 :(得分:3)
您可能已经知道,但使用output_test_stream
作为std::ostream
有效:
class foo {
// [...]
friend
std::ostream& operator<< ( std::ostream &os, const foo &f );
};
std::ostream& operator<< ( std::ostream &os, const foo &f ) {
return os << f.data;
}
答案 1 :(得分:3)
所以我想我有一个解释,但还没有解决方案。 output_test_stream
通过继承wrap_stringstream
来实现其流功能。这个插入操作符是一个免费的函数模板,如下所示:
template <typename CharT, typename T>
inline basic_wrap_stringstream<CharT>&
operator<<( basic_wrap_stringstream<CharT>& targ, T const& t )
{
targ.stream() << t;
return targ;
}
// ... further down in the same header
typedef basic_wrap_stringstream<char> wrap_stringstream;
使用output_test_stream
作为流类型调用运算符,这使得它成为返回类型。然后,您的运算符调用上面的运算符,并传播返回值。但是,上述运算符的返回值是运算符的返回类型的超类。当编译器尝试创建您想要返回的引用时,它会发生阻塞,因为它无法从对超类的引用初始化对子类的引用,即使它们都引用同一个对象。这有什么意义吗?
答案 2 :(得分:0)
这是一个错字吗?你写了
foo.append(str, strlen(str));
但是foo
是类的名称而不是对象。