Boost logo

Boost Users :

From: Will Bryant (will_at_[hidden])
Date: 2005-09-01 03:12:05


Hi all,

I've been using Boost.Test lately and in general it's working well
(thanks Gennadiy!).

However, I'm having trouble with BOOST_CHECK_EQUAL_COLLECTIONS when my
collections are of non-primitive types. For example, if I try:

    vector<wstring> test1, test2;
    BOOST_CHECK_EQUAL_COLLECTIONS(test1.begin(), test1.end(),
test2.begin(), test2.end());

I get a compiler error along the lines of
"h:\libraries\boost\boost\test\utils\wrap_stringstream.hpp(66) : error
C2679: binary '<<' : no operator found which takes a right-hand operand
of type 'const std::basic_string<_Elem,_Traits,_Ax>' (or there is no
acceptable conversion)" (with _Elem being wchar_t in this case, and
_Traits and _Ax having the usual defaults).

Looking at the source I see that BOOST_CHECK_EQUAL_COLLECTIONS is using
equal_coll_impl, which is creating a predicate_result and using the
stream insertion operator on the wrap_stripstream returned by its
message() method. wrap_stringstream has an unspecialized template which
delegates to the << operator of the backing ostringstream/ostrstream:

    template <typename CharT, typename T>
    inline basic_wrap_stringstream<CharT>&
    operator<<( basic_wrap_stringstream<CharT>& targ, T const& t )
    {
        targ.stream() << t;
        return targ;
    }

Since that backing ostringstream descends from ostream, I would have
thought that all I needed to do was to ensure that there is a operator
<< (ostream&, wstring const&) defined, like this:

    ostream& operator << (ostream& ostr, wstring const& str)
    {
        ostr << "I'd put a wstring-to-string function here instead of
this constant";
        return ostr;
    }

Hower this doesn't work - although I can now compile:
    ostringstream oss;
    oss << wstring(L"test");
successfully, if I try:
    boost::wrap_stringstream wss;
    wss << wstring(L"test");
or:
    boost::test_tools::predicate_result res(true);
    res.message() << wstring(L"test");
I get the same error as above.

Interestingly, if I change that << operator implementation so that it
takes and returns a wrap_stringstream, instead of an ostream:

    boost::wrap_stringstream& operator << (boost::wrap_stringstream&
ostr, const wstring& str)
    {
        ostr << "I'd put a wstring-to-string function here instead of
this constant";
        return ostr;
    }

then I can compile 'wss << wstring(L"test")' and ' res.message() <<
wstring(L"test")' OK. This is weird because it suggests to me that that
unspecialized wrap_stringstream template that delegates to the
ostringstream's << isn't working properly.

But weirder is that even having done that, using
BOOST_CHECK_EQUAL_COLLECTIONS still produces the same compilation error,
even though it's making the same operator call - I can't see why. Am I
missing something here?

I also tried specializing print_log_value:

    namespace boost { namespace test_tools { namespace tt_detail {
        template<>
        struct print_log_value<std::wstring> {
            void operator()(std::ostream& ostr, const std::wstring& str) {
                ostr << "I'd put a wstring-to-string function here
instead of this constant";
            }
        };
    }}}

But that didn't help either - same error.

I'm primarily using Visual Studio 2005, but I have exactly the same
problems under gcc 3.3.5 too.

Any suggestions?

Cheers,
Will

-- 
Will Bryant
http://carcino.gen.nz/
will_at_[hidden]
+64 21 655 443

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net