代码之家  ›  专栏  ›  技术社区  ›  Robert S. Barnes Antoni

boost.test output_test_流使用模板化的输出运算符失败

  •  3
  • Robert S. Barnes Antoni  · 技术社区  · 14 年前

    我有一堂课:

    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> >’
    

    发生什么事?

    我在用 Boost 1.34.1 在Ubuntu 8.04上。

    3 回复  |  直到 14 年前
        1
  •  3
  •   Björn Pollex    14 年前

    所以我想我有一个解释,但还没有解决办法。 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;
    

    接线员打电话来 输出测试流 作为流类型,因此它是返回类型。然后,您的运算符调用上述运算符,并只传播返回值。但是,上面的运算符的返回值是运算符的返回类型的超类。当编译器试图创建您想要返回的引用时,它会阻塞,因为它无法从对超类的引用初始化对子类的引用,即使两者都引用同一个对象。有什么意义吗?

        2
  •  3
  •   mkluwe    14 年前

    你可能已经知道了,但是使用 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;
    }
    
        3
  •  0
  •   mkluwe    14 年前

    是打字吗?你写

    foo.append(str, strlen(str));
    

    但是 foo 是类的名称,而不是对象。