Ok , so this is defiantly not the cleanest/shortest solution but here is one way of doing it:
namespace custom
{
struct sep
{
sep(const std::string & s)
:separator(s)
{
}
std::string separator;
};
}
typedef std::basic_ostream<char, std::char_traits<char> > CoutType;
typedef CoutType& (*StandardEndLine)(CoutType&);
class SeparatorWrap
{
public:
SeparatorWrap(std::ostream & _ofs, const custom::sep & s)
: ofs(_ofs)
, separator(s)
{}
template <class W>
SeparatorWrap& operator << (W && w)
{
ofs << separator.separator << w;
return (*this);
}
ostream & operator << (const StandardEndLine &)
{
//writing std::endl will remove the separator
return ofs << std::endl;
}
protected:
std::ostream & ofs;
custom::sep separator;
};
class SeparatorWrapFirst
{
public:
SeparatorWrapFirst(std::ostream & _ofs, const custom::sep & s)
: ofs(_ofs)
, separator(s)
{}
template <class W>
SeparatorWrap operator << (W && w)
{
ofs << w;
return SeparatorWrap(ofs, separator);
}
ostream & operator << (const StandardEndLine &)
{
//writing std::endl will remove the separator
return ofs << std::endl;
}
protected:
std::ostream & ofs;
custom::sep separator;
};
SeparatorWrapFirst operator << (std::ostream & ofs,const custom::sep & s)
{
return SeparatorWrapFirst(ofs, s);
}
int main()
{
std::cout << custom::sep(", ") << 1 << "two" << 3 << std::endl;
}
Here is how it works:
std::cout << custom::sep(", ")
returns a class of type SeparatorWrapFirst
(using the global operator <<
) which is used to write one value without separators the output. This is because if you have one element you don't need to write the separator.
After the first operator <<
from SeparatorWrapFirst
is called, the class SeparatorWrap
is returned and that prints with the separator also. This is for multiple values.
Edit:
So from the comments (@gexicide) it appears that i's possible to put custom manipulator inside std::cout
. This could allow you to do something like:
std::cout << custom::sep(", ");
std::cout << 1 << "two" << 3 << std::endl;
Where the first solution from above will not work for this.