I want to print all the arguments of function using variadic templates feature of C++11. And I did the following:

struct concatenate
{

    template< typename ...ARGS >
    explicit
    concatenate(ARGS const & ...args)
    {
        cat(args...);
    }

    /*explicit*/
    operator std::string const () const
    {
        return oss.str();
    }

private :

    std::ostringstream oss;

    void cat() const
    { ; }

    template< typename T, typename ...ARGS >
    void cat(T const & head, ARGS const & ...tail)
    {
        if (oss.tellp() > 0) {
            oss << ' ';
        }
        oss << head;
        cat(tail...);
    }

};

Then I try to test it:

std::cout << '\'' << concatenate(1, 2, 3, 4, std::string("ololo"), "alala", 'o', 1.2, 1.2L, 1.2f) << '\'' << std::endl;

but then given the code does not compile with error:

error: cannot bind 'std::basic_ostream<char>' lvalue to 'std::basic_ostream<char>&&' c:\mingw\lib\gcc\mingw32\4.7.0\include\c++\ostream:600: error: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = concatenate]'

What is the nature of the error? After all, the compiler has no choice but to use a conversion operator. It isn't?

有帮助吗?

解决方案

operator << for class template std::basic_string is defined as (free) function template. In contrast with non-template functions, template argument deduction doesn't involve possible argument conversions. Templated operator << for basic_string needs exactly a string as it right argument and implicit conversion (from concatenate to string) doesn't work.

其他提示

Because you're not using the explicit conversion operator and you have not overloaded operator<< for your class it tries to call:

template <class charT, class traits, class T>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>&& os, const T& x);

Using the explicit conversion

std::string(concatenate(1, 2, 3, 4, std::string("ololo"), "alala", 'o', 1.2, 1.2L, 1.2f))

does the right thing.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top