Friday 1 December 2017

c++ - How to implement StringBuilder class which to be able to accept IO manipulators

itemprop="text">

I wrote the following utility 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 Args>
explicit StringBuilder(Args&&... args)

{
append(std::forward(args)...);

}

template
StringBuilder&
append(const T& arg)
{
_data <<
arg;

return *this;
}

template

StringBuilder& append(const T& arg,
Args&&... args)
{
_data << arg;

append(std::forward(args)...);
return *this;

}


std::string toString() const
{

return _data.str();
}

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

}


template

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

private:
std::ostringstream
_data;
};



cannot
compile. The error message is quite long to paste here, but it start
with:




main.cpp: In
function ‘int main()’: main.cpp:37:8: error: no match for
‘operator<<’
(operand types are ‘utils::StringBuilder’ and
‘’)
sb <<
endl;





and
ends with:





/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);





How
to make StringBuilder to be able to accept std::endl and other
IO manipulators?


itemprop="text">
class="normal">Answer



endl (as
well as the iomanip operands) is a
function.



Just write an overload like
this



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

}


..
or as an external operator like
this



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


...and it will
work for all of them


No comments:

Post a Comment

php - file_get_contents shows unexpected output while reading a file

I want to output an inline jpg image as a base64 encoded string, however when I do this : $contents = file_get_contents($filename); print &q...