Boost logo

Boost Users :

From: Patrick Mézard (pmezard_at_[hidden])
Date: 2005-03-02 05:25:11


Vladimir Prus <ghost <at> cs.msu.su> writes:

>
> Patrick M?zard wrote:
>
> > namespace testns
> > {
> >
> > struct Test
> > {
> ....
> > };
> >
> > namespace
> > {
> >
> > std::ostream& operator<<(std::ostream& o, Test const& t)
> > {
> > return o<<t.s;
> > }
>
> ...
> > Does not compile and gives me a:
> > C2679: binary 'operator' : no operator defined which takes a right-hand
> > operand of type 'const testns::Test' (or there is no acceptable
> > conversion), the failure being issued by "void
> > boost::test_tools::tt_detail::print_log_value<T>::operator
> > ()(std::ostream &,const T &)"
> >
> > However, if I define operator<< as a public member of testns::Test it
> > compiles. Same thing if I move it outside the anonymous namespace, with or
> > without static linkage.
>
> I think defining operator<< in the same namespace as the class 'Test' is the
> only way. Otherwise, it won't be found by ADL and ADL is the only way to
> boost.test to find your operator<<.

Thank you for your answer. I did not know that ADL treats normal and anonymous
namespaces differently (and cannot find anything related in google.groups or
other mailing lists).

However, it does not work with typedefed types. Here is a new example :

//*********************
#include <boost/test/unit_test.hpp>
using boost::unit_test::test_suite;

namespace testns
{

typedef std::pair<int, std::string> Test;

std::ostream& operator<<(std::ostream& o, Test const& t)
{
    return o<<t.first<<t.second;
}

namespace
{

void free_test_function()
{
    Test t1(1, "test1"), t2(2, "test2");
    BOOST_CHECK_EQUAL(t1, t2);
}

} //namespace

} //namespace testns

test_suite*
init_unit_test_suite( int, char* [] ) {
    test_suite* test= BOOST_TEST_SUITE( "Unit test example 1" );

    test->add( BOOST_TEST_CASE( &testns::free_test_function ));

    return test;
}

//*********************

I get the same error (C2679) again with the same function instantiation "void
boost::test_tools::tt_detail::print_log_value<T>::operator ()(std::ostream
&,const T &)".

Until now, to make it works I moved operator<< into "namespace boost { namespace
test_tools { namespace tt_detail" but that's clearly not the way to go. Can you
think of any workaround for this one (workaround or just a correct way to write
that :-). I do not pretend to understand anything about ADL...).

Patrick Mézard


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