首页 文章

如何实现能够接受IO操纵器的StringBuilder类

提问于
浏览
0

我写了以下实用程序C类 .

/*!
 * \brief The \b StringBuilder class is used for efficiently constructing long
 * strings out of many small ones. Internally it uses \b std::ostringstream and
 * its advantage compared to usage of raw \b std::ostringstream is that it is
 * capable to be used on single line and implicitly converted to \b std::string
 * everywhere this type is expected.
 * \code{.cpp}
 * void foo(const std::string& s);
 * foo(utils::StringBuilder("The answer is: ") << 42 << std::endl);
 * \endcode
 */
class StringBuilder
{
public:
    StringBuilder() = default;

    template <class... Args>
    explicit StringBuilder(Args&&... args)
    {
        append(std::forward<Args>(args)...);
    }

    template <class T>
    StringBuilder& append(const T& arg)
    {
        _data << arg;
        return *this;
    }

    template <class T, class... Args>
    StringBuilder& append(const T& arg, Args&&... args)
    {
        _data << arg;
        append(std::forward<Args>(args)...);
        return *this;
    }

    std::string toString() const
    {
        return _data.str();
    }

    operator std::string() const
    {
        return toString();
    }

    template <class T>
    StringBuilder& operator<<(const T& object)
    {
         return append(object);
    }

private:
    std::ostringstream _data;
};

无法编译 . 这里粘贴的错误消息很长,但它始于:

main.cpp:在函数'int main()'中:main.cpp:37:8:错误:'operator <<'不匹配(操作数类型是'utils :: StringBuilder'和'')sb << endl ;

并结束于:

/ usr / include / c /4.8.3/bits/basic_string.h:2753:5:注意:模板参数推断/替换失败:main.cpp:36:33:注意:'utils :: StringBuilder'不是派生的来自'std :: basic_ostream <_CharT,_Traits>'cout <<(StringBuilder()<< endl);

如何使StringBuilder能够接受 std::endl 和其他IO操纵器?

1 回答

  • 2

    endl(以及iomanip操作数)是一个函数 .

    只需写一个像这样的重载

    StringBuilder& operator<<(ostream& func(ostream&))
    {
        _data << func;
        return *this;
    }
    

    ..或像这样的外部运营商

    StringBuilder& operator<<(StringBuilder& sb, ostream& func(ostream&)) ...
    

    ......它将适用于所有人

相关问题