Keine Frage, aber auch nicht Wert für einen Beitrag in den Ressourcen ...
Bin heute über einen alten Code aus C++11 Zeiten gestolpert, in dem ich operator<< für std::array und std::vector überladen habe, sofern aus char-Typen bestehend. Ziemlich viel Code für so eine simple Aufgabe.
Als ich die ersten beiden Variablen gesehen habe ist mir sofort aufgefallen - sieht verdächtig nach string_view aus. Und - wie nicht anders zu erwarten - lässt sich der Code damit auf eine Zeile eindampfen. Natürlich wird der alte Code so oder ähnlich immer noch ausgeführt. Allerdings ist er in der Implementierung für die Überladung des string_streams verschwunden.
Hier mal der Code als Anschauungsmaterial und, falls jemand Lust drauf hat, zum Zerreißen und Fragen stellen.
// Edit: der zweite Parameter ist eine Referenz und keine Kopie
Bin heute über einen alten Code aus C++11 Zeiten gestolpert, in dem ich operator<< für std::array und std::vector überladen habe, sofern aus char-Typen bestehend. Ziemlich viel Code für so eine simple Aufgabe.
Als ich die ersten beiden Variablen gesehen habe ist mir sofort aufgefallen - sieht verdächtig nach string_view aus. Und - wie nicht anders zu erwarten - lässt sich der Code damit auf eine Zeile eindampfen. Natürlich wird der alte Code so oder ähnlich immer noch ausgeführt. Allerdings ist er in der Implementierung für die Überladung des string_streams verschwunden.
Hier mal der Code als Anschauungsmaterial und, falls jemand Lust drauf hat, zum Zerreißen und Fragen stellen.
C++:
#include <iostream>
#include <iomanip>
#include <type_traits>
#include <array>
#include <vector>
#include <string_view>
/*
template<typename classT, typename charT, typename traitsT = std::char_traits<charT>>
std::basic_ostream<charT, traitsT>& operator<<(std::basic_ostream<charT, traitsT>& ostr, const classT& string_like)
{
// `string_like` has to have a `data()` method and its return type must be
// brace-initializable to a pointer to const char_type of the ostream
const charT* const str{ string_like.data() };
// `string_like` has to have a `size()` method
// its return type might get narrowed (because streamsize is a signed type)
const std::streamsize length(string_like.size());
if (typename std::basic_ostream<charT>::sentry{ ostr })
{
try
{
const auto ostr_width{ ostr.width() };
if (ostr_width > length)
{
const auto left_is_set{ (ostr.flags() & std::basic_ostream<charT>::adjustfield) == std::basic_ostream<charT>::left };
if (!left_is_set)
{
for (auto pad{ ostr_width - length }; pad-- > 0; )
{
if (ostr.rdbuf()->sputc(ostr.fill()) == traitsT::eof())
{
ostr.setstate(std::basic_ios<charT, traitsT>::badbit);
break;
}
}
}
if (ostr.good() && ostr.rdbuf()->sputn(str, length) != length)
ostr.setstate(std::basic_ios<charT, traitsT>::badbit);
if (left_is_set && ostr.good())
{
for (auto pad{ ostr_width - length }; pad-- > 0; )
{
if (ostr.rdbuf()->sputc(ostr.fill()) == traitsT::eof())
{
ostr.setstate(std::basic_ios<charT, traitsT>::badbit);
break;
}
}
}
}
else if (ostr.rdbuf()->sputn(str, length) != length)
ostr.setstate(std::basic_ios<charT, traitsT>::badbit);
ostr.width(0);
}
catch (...)
{
ostr.setstate(std::basic_ios<charT, traitsT>::badbit);
}
}
else
ostr.setstate(std::basic_ios<charT, traitsT>::badbit);
return ostr;
}
*/
template<typename classT, typename charT, typename traitsT = std::char_traits<charT>>
std::basic_ostream<charT, traitsT>& operator<<(std::basic_ostream<charT, traitsT>& ostr, const classT& string_like)
{
return operator<<(ostr, std::basic_string_view<charT, traitsT>{ string_like.data(), string_like.size() });
}
int main()
{
const std::array arr{ 't', 'e', 's', 't' };
const std::vector vec{ 'c', 'o', 'd', 'e' };
std::cout << arr << std::endl;
std::cout << vec << std::endl;
std::cout << std::setw(10) << arr << std::endl;
std::cout << std::setw(10) << vec << std::endl;
std::cout << std::setw(10) << std::left << arr << "foo" << std::endl;
std::cout << std::setw(10) << std::left << vec << "foo" << std::endl;
}
// Edit: der zweite Parameter ist eine Referenz und keine Kopie
Zuletzt bearbeitet: