1

我想使用C++11 的可变参数模板功能打印函数的所有参数。我做了以下事情:

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...);
    }

};

然后我尝试测试它:

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

但随后给出的代码没有编译错误:

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]'

错误的性质是什么?毕竟,编译器别无选择,只能使用转换运算符。不是吗?

4

2 回答 2

3

模板std::basic_string 的运算符 << 被定义为(免费)函数模板。与非模板函数相比,模板参数推导不涉及可能的参数转换。basic_string 的模板化运算符 << 需要一个字符串,因为它是正确的参数,并且隐式转换(从连接到字符串)不起作用。

于 2012-11-29T16:06:38.683 回答
1

因为您没有使用显式转换运算符,并且您没有operator<<为您的类重载它尝试调用:

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

使用显式转换

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

做正确的事。

于 2012-11-29T15:53:28.860 回答