如何实现能够接受 IO 操纵器的 StringBuilder class
How to implement StringBuilder class which to be able to accept IO manipulators
我编写了以下实用程序 C++ class。
/*!
* \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: In function ‘int main()’: main.cpp:37:8: error: no match for
‘operator<<’ (operand types are ‘utils::StringBuilder’ and
‘’)
sb << endl;
并以:
结尾
/usr/include/c++/4.8.3/bits/basic_string.h:2753:5: note: template
argument deduction/substitution failed: main.cpp:36:33: note:
‘utils::StringBuilder’ is not derived from ‘std::basic_ostream<_CharT,
_Traits>’
cout << (StringBuilder() << endl);
如何让StringBuilder能够接受std::endl
和其他IO操作器?
endl(以及 iomanip 操作数)是一个函数。
像这样写一个重载
StringBuilder& operator<<(ostream& func(ostream&))
{
_data << func;
return *this;
}
.. 或者像这样的外部操作员
StringBuilder& operator<<(StringBuilder& sb, ostream& func(ostream&)) ...
...它对所有人都有效
我编写了以下实用程序 C++ class。
/*!
* \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: In function ‘int main()’: main.cpp:37:8: error: no match for ‘operator<<’ (operand types are ‘utils::StringBuilder’ and ‘’) sb << endl;
并以:
结尾/usr/include/c++/4.8.3/bits/basic_string.h:2753:5: note: template argument deduction/substitution failed: main.cpp:36:33: note:
‘utils::StringBuilder’ is not derived from ‘std::basic_ostream<_CharT, _Traits>’ cout << (StringBuilder() << endl);
如何让StringBuilder能够接受std::endl
和其他IO操作器?
endl(以及 iomanip 操作数)是一个函数。
像这样写一个重载
StringBuilder& operator<<(ostream& func(ostream&))
{
_data << func;
return *this;
}
.. 或者像这样的外部操作员
StringBuilder& operator<<(StringBuilder& sb, ostream& func(ostream&)) ...
...它对所有人都有效