C++ Overload operator << with something other than ostream - c++

I'm trying to show off variety on a piece of course work and hoped to use the << operator to easily add variables to a list. Eg:
UpdateList<string> test;
test << "one" << "two" << "three";
My problem, is that EVERY SINGLE example of the << operator is to do with ostream.
My current attempt is:
template <class T> class UpdateList
{
...ect...
UpdateList<T>& operator <<(T &value)
{
return out;
}
}
Does anyone know how I can achieve this, or is it actually not possible inside C++?

You should use const T& value.
Following fragment of code should work fine
UpdateList<T>& operator << (const T& value)
{
// push to list
return *this;
}
or
UpdateList<T>& operator << (T value)
{
// push to list
return *this;
}
in C++11 (thanks to rightfold)

You would (typically) want to declare it as a non-class member:
template<typename T>
UpdateList<T>& operator<<(UpdateList<T>& lst, const T& value)
{
lst.add(value); // whatever your add/insert method is goes here
return lst;
}

You' ll need an overloaded operator<<() outside the class:
template<typename T>
UpdateList<T>& operator<<(UpdateList<T>& out, const T& value)
{
return out;
}

Related

correct template method to wrap a ostream

Given a class
class ostreamWrapper
{
private:
ostream * str;
public:
ostreamWrapper operator << (const char *);
}
where ostream * str will point to std::cout and ostreamWrapper operator << (const char *) sends the given text to the wrapped ostream str.
In this case, I can only instance << "const char * text" and no other printable data. Unlike directly <<ing a std::cout or std::cerr.
How can the operator method be implemented so it accepts any type of data just as std::cout or std::cerr directly do?
First, write a public operator<< template so it can accept any type and simply forward it to the wrapped ostream.
template <class T>
ostreamWrapper& operator<<(T&& x) {
*str << std::forward<T>(x);
return *this;
}
Second, in order to accept insertion of stream manipulator templates such as std::endl, add a second public operator<< that specifically accepts manipulators intended for the wrapped ostream:
ostreamWrapper& operator<<(ostream& (*manip)(ostream&)) {
*str << manip;
return *this;
}
Omitting the second overload will cause insertion of overloaded manipulators or manipulator templates to fail with "ambiguous overload" or similar error messages.
See an example of the proposed implementation, it would deduce the template parameter type and print accordingly, if you could use C++11 see #Brian answer:
#include <iostream>
using namespace std;
class ostreamWrapper {
private:
ostream* str;
public:
ostreamWrapper(ostream* str_v) : str(str_v) {}
template <typename T>
ostreamWrapper& operator<<(const T& t) {
if (str)
*str << t;
return *this;
}
};
int main() {
ostreamWrapper osw(&std::cout);
osw << 1 << " texto " << std::string(" otro texto ") << 1.2345;
return 0;
}

Template and operator overloading

I was going through code... I found a template class which is declared as shown below.
template <class T>
class tType
{
public:
T value;
T operator=(T val){ value = val; return value; }
tType<T> operator=(tType<T> &val){ value = val.value; return *this; }
operator T(){ return value; }
};
I also found operator overloaded like below...
******1******
template <class T>
bool operator==(T& val, tType<T>& tval) { return(val == tval.value); }
I didn't understand when the above operator gets called... cos when I did...
int main(void)
{
tType<int> x;
x = 5;
if (5 == x)
{
cout << "Both are equal" << endl;
}
return 0;
}
The above said operator was not getting called... and was still working... I also wrote below code for testing and the below code snippet is getting called...
template<class T>
bool operator==(int x, tType<T>& val) { return (x == val.value); }
I wasn't to know who to call *****1*****
It's right that the reason your operator== isn't called is because of the missing const identifier. In this case, the literal 5 is unable to be passed as a variable reference for the paramater T& val. But, that's not quite the whole story.
As you point out, the code still compiles and runs even though the function isn't being called.
The reason your code still works is because of the conversion operator: operator T(){ return value; }.
A conversion operator allows implicit casts from one type to another. For example:
struct Number {
Number(int x) : value(x) { }
operator int() { return value; }
private:
int value;
};
int main() {
Number n(5);
int x = n; // 5 -- operator int() at work
int y = n + x; // 10 -- operator int() at work
Number z = x + y; // 15 -- Number(int) at work
cout << x <<" "<< y <<" "<< z << endl;
return 0;
}
Here, operator int() allows n to convert into an int for assignment to x and to convert to an int for addition with x (the resultant int is then assigned to y), while the unary constructor Number(int) allows the result of x + y to convert back to a Number.
In your code, 5 == x still compiles because the tType<int> x is converted into an int via its operator int() member function, and then that resultant int is compared against the literal 5.
However, this probably isn't a very good design for a class. For example, in order to compare two tType<T>s, a cast into T will be required for one of them.
template <class T>
bool operator==(const T& val, const tType<T>& tval) {
cout << "operator==(const T& val, const tType<T>& tval) was called." << endl;
return(val == tval.value);
}
//...
cout << ( tType<int>() == tType<int>() ) << endl; // calls operator==(const T&, const tType<T>&)
You would rather have an operator== for two tType<T>s.
Another even bigger problem is that this is not symmetric:
cout << (x1 == 5) << endl; // calls operator==(int,int) (the built-in function)
Yikes!
To address all of these, there is a very straightforward design solution. This is taken from Scott Meyers' book Effective C++ Third Edition (a phenomenal book).
Instead of converting back to a T with a conversion operator, the class should include an implicit unary constructor to convert T's up to tType<T>s, and should declare exactly one operator== for tType<T>s:
template <class T>
class tType
{
public:
tType<T>(const T &val) : value(val) { } // unary non-explicit constructor
tType<T> operator=(const tType<T> &val){ value = val.value; return *this; } // only need one
T val() { return value; }
private:
T value; // Note also value is private (encapsulation)
};
template<class T>
bool operator==(const tType<T>& a, const tType<T>& b) { return ( a.val() == b.val() ); }
The important changes:
Added a constructor that takes a single value; this allows converting Ts into tTypes.
Removed the assignment operator taking Ts (because now we can convert them to tTypes.
Only have one equality operator and it takes two const tType<T>&s, meaning operator== can handle any combination of Ts and tType<T>s (or, even better, anything convertible into either of those).
The == operator attempts to bind non-const references to the arguments - values like "5" are not amenable to that... the parameters should be const:
template <class T>
bool operator==(const T& val, const tType<T>& tval) { return val == tval.value; }
As that will still only support e.g. 5 == my_tType and not my_tType == 5, you may want to also provide...
template <class T>
bool operator==(const tType<T>& tval, const T& val) { return val == tval.value; }
...and for my_tType1 == my_tType2...
template <class T>
bool operator==(const tType<T>& tval1, const tType<T>& tval2) {
return tval1.value == tval2.value; }
This gives you maximum control of the comparisons. An alternative is to allow implicit construction of a tType from a T argument, but implicit construction and conversion operators are generally discouraged these days - they can lead to ambiguities and accidental creation of temporaries that can be hard to debug. A topic for another question....
When you say "The above said operator was not getting called... and was still working" - what was actually happening was that tType::operator T() (which returns value;) was being implicitly called, returning an int that could be compared - as an int - to 5. Hence - you had a comparison, but not using the custom operator==. This is a normal result of finding the "best match" for a function call.
Change the function
template <class T>
bool operator==(T& val, tType<T>& tval) { return(val == tval.value); }
to
template <class T>
bool operator==(T const& val, tType<T> const& tval) { return(val == tval.value); }
or
template <class T>
bool operator==(T val, tType<T> tval) { return(val == tval.value); }
Your function was not getting called since 5 cannot be converted to int&.

boost::format and custom printing a std containers

I have a function in my namespace ns that helps me print STL containers. For example:
template <typename T>
std::ostream& operator<<(std::ostream& stream, const std::set<T>& set)
{
stream << "{";
bool first = true;
for (const T& item : set)
{
if (!first)
stream << ", ";
else
first = false;
stream << item;
}
stream << "}";
return stream;
}
This works great for printing with operator << directly:
std::set<std::string> x = { "1", "2", "3", "4" };
std::cout << x << std::endl;
However, using boost::format is impossible:
std::set<std::string> x = { "1", "2", "3", "4" };
boost::format("%1%") % x;
The problem is fairly obvious: Boost has no idea that I would like it to use my custom operator << to print types which have nothing to do with my namespace. Outside of adding a using declaration into boost/format/feed_args.hpp, is there a convenient way to make boost::format look for my operator <<?
The solution I actually went with is quite similar to Answeror's, but it works for anything:
namespace ns
{
template <typename T>
class FormatWrapper
{
public:
explicit FormatWrapper(const T& x) :
ref(x)
{ }
friend std::ostream& operator<<(std::ostream& stream,
const FormatWrapper<T>& self
)
{
// The key is that operator<< is name lookup occurs inside of `ns`:
return stream << self.ref;
}
private:
const T& ref;
};
template <typename T>
FormatWrapper<T> Formatable(const T& x)
{
return FormatWrapper<T>(x);
}
}
So usage is:
boost::format("%1%") % Formatable(x);
I think the most clean way is to provide a thin wrapper in your own namespace for each of the operators you want to override. For your case, it can be:
namespace ns
{
namespace wrappers
{
template<class T>
struct out
{
const std::set<T> &set;
out(const std::set<T> &set) : set(set) {}
friend std::ostream& operator<<(std::ostream& stream, const out &o)
{
stream << "{";
bool first = true;
for (const T& item : o.set)
{
if (!first)
stream << ", ";
else
first = false;
stream << item;
}
stream << "}";
return stream;
}
};
}
template<class T>
wrappers::out<T> out(const std::set<T> &set)
{
return wrappers::out<T>(set);
}
}
Then use it like this:
std::cout << boost::format("%1%") % ns::out(x);
You can try something like this:
namespace boost // or __gnu_cxx
{
using np::operator<<;
}
#include <boost/format/feed_args.hpp>
The problem as already noted is because of ADL (argument dependent lookup - often attributed to Andrew Koenig, but I believe he shouldn't get all the blame).
Even in your local context it wouldn't work in a template function where you intend to use your operator<<.
One cheating trick is to put the operator<< you define into namespace std. That is verboten, but it might work in your case, but only if it is put before its usage and that might be the problem.
There might be further options, such as defining your own Set template. I experimented with
template<typename T> using Set=std::set<T>;
but couldn't get a solution that worked without the
using np::operator<<;
yuyoyuppe provided.

C++ output operator overload

I've been working on this school assignment. The assignment told us to make an object which had it's output operator ( << ) overloaded.
Here's my code:
#include <ostream>
using namespace std;
template <class T>
class CustomObject {
string print() {
string text = "";
for (int i = 0; i < num_items(); i++) {
text += queue[i];
text += " | \n";
}
return text;
}
friend std::ostream& operator <<(std::ostream &output, CustomObject &q) {
output << "" << q.print();
return output;
}
}
So I instantiate this object like this:
CustomObject<int> co();
and call its output method:
std::cout << co();
Which would inevitably call the print method, and return the string to the default output stream.
But, there's no visible output in my console/debugger.
What am I missing here?
PS this is not the complete class, it's generic because of several other methods and functionality that is not necessary to be shown here.
PPS the num_items() and queue variables are part of said rest, this class is a PriorityQueue object. So, queue is an array of the specified type (hence the generic declaration) and num_items() just returns the count of the array.
CustomObject<int> co();
That's a function declaration. Leave out the parenthesis.
std::cout << co();
Why are you appling operator() to co? Again, leave out the parenthesis. This should work:
CustomObject<int> co;
std::cout << co;
Alas, building and returning a string from a print method is hardly idiomatic C++. Here is what I would do:
template <typename T>
class CustomObject
{
// ...
public:
void print(std::ostream& os) const
{
for (int i = 0; i != num_items(); ++i)
{
os << queue[i] << " | \n";
}
}
};
std::ostream& operator<<(std::ostream& os, const CustomObject& object)
{
object.print(os);
return os;
}
If you want to be able to print temporary objects a well, you should make the parameter a const reference:
CustomObject const& q)

Does C++ have an equivilent to Python's __setitem__

Just as the title asks, does C++ have the equivalent of Python's setitem and getitem for classes?
Basically it allows you to do something like the following.
MyClass anObject;
anObject[0] = 1;
anObject[1] = "foo";
basically, you overload the subscript operator (operator[]), and it returns a reference (so it can be read as well as written to)
You can overload the [] operator, but it's not quite the same as a separate getitem/setitem method pair, in that you don't get to specify different handling for getting and setting.
But you can get close by returning a temporary object that overrides the assignment operator.
To expand on Earwicker post:
#include <string>
#include <iostream>
template <typename Type>
class Vector
{
public:
template <typename Element>
class ReferenceWrapper
{
public:
explicit ReferenceWrapper(Element& elem)
: elem_(elem)
{
}
// Similar to Python's __getitem__.
operator const Type&() const
{
return elem_;
}
// Similar to Python's __setitem__.
ReferenceWrapper& operator=(const Type& rhs)
{
elem_ = rhs;
return *this;
}
// Helper when Type is defined in another namespace.
friend std::ostream& operator<<(std::ostream& os, const ReferenceWrapper& rhs)
{
return os << rhs.operator const Type&();
}
private:
Element& elem_;
};
explicit Vector(size_t sz)
: vec_(sz)
{
}
ReferenceWrapper<const Type> operator[](size_t ix) const
{
return ReferenceWrapper<const Type>(vec_[ix]);
}
ReferenceWrapper<Type> operator[](size_t ix)
{
return ReferenceWrapper<Type>(vec_[ix]);
}
private:
std::vector<Type> vec_;
};
int main()
{
Vector<std::string> v(10);
std::cout << v[5] << "\n";
v[5] = "42";
std::cout << v[5] << "\n";
}
It's not portable, but MSVC has __declspec(property), which also allows indexers:
struct Foo
{
void SetFoo(int index, int value) { ... }
int GetFoo(int index) { ... }
__declspec(property(propget=GetFoo, propput=SetFoo)) int Foo[];
}
other than that, Earwicker did outline the portable solution, but he's right that you'll run into many problems.