Is nesting overloaded operators possible ? I would like to nest << inside a ()
template<class T>
struct UnknownName
{
T g;
T&operator<<(std::ostream&os, const T&v){return os<<v;}
bool operator()(const T&v)
{
if(v==g)
//do the streaming << then return true
else return false;
}
};
Would you please help me out ? I am afraid my example is unreal enough to you, please just ask if you still have any doubts. Sincerely.
I can't really tell what you're asking, but I assume you mean write a class to the ostream& that gets passed to operator<<. First you have to make up a way to convert a T to a string representation. I'll assume the function TToString does that.
template<class T>
struct UnknownName
{
T g;
bool operator()(const T&v)
{
if(v==g) {
cout << v;
return true;
}
return false;
}
friend std::ostream& operator<<(std::ostream& os, const T& v) {
return os << TToString(v);
}
};
Sorry if I misinterpreted your question.
The best I can think of would be to have operator<< return a specific type, and then overload operator() to accept that type:
#include <cstdio>
namespace {
struct Foo {
struct Bar {
int i;
};
Foo& operator()(const Bar& b)
{
std::printf("bar, %d\n", b.i);
return *this;
}
// obviously you don't *have* to overload operator()
// to accept multiple types; I only did so to show that it's possible
Foo& operator()(const Foo& f)
{
std::printf("foo\n");
return *this;
}
};
Foo::Bar operator<<(const Foo& f, const Foo& g)
{
Foo::Bar b = { 5 };
return b;
}
}
int main()
{
Foo f, g, h;
f(g << h);
f(g);
}
This isn't a common idiom, to say the least.
Related
For example, I've written a class called Length:
class Length {
public:
void setValue(float);
private:
float value_;
};
void
Length::setValue(float newValue) {
value_ = newValue;
}
void print(float value) {
std::cout << value;
}
void computeStuff(float value) {
//do the computing
}
int main() {
Length width;
width.setValue(5);
std::cout << width; // <-- this is actually just an example
//what I actually want is:
print(width); // print 5
//or perhaps even
computeStuff(width);
return 0;
}
Now how to make width return value_ or 5?
Technically, width is not an instance name, it's a name of a variable of type Length. You can change your code to retrieve a variable in two ways:
Add a friend operator << for Length that does the printing, or
Add an implicit conversion operator from Length to float.
The first approach works only for output. You cannot pull the value directly:
friend ostream& operator <<(ostream& out, const Length& len) {
out << len.value_;
return out;
}
The second approach looks like this:
class Length {
...
public:
operator float() const { return value_; }
};
You must overload operator<< for your custom type, something like:
class Length
{
..
friend std::ostream& operator<<(std::ostream& os, const Length& o);
..
}
std::ostream& operator<<(std::ostream& os, const Length& o)
{
os << o.value_;
return os;
}
Mind that this
must be non member
is nothing special , just an operator overload applied to a standard way of inserting things into stream of <iostream>
You need to define an operator() method to print the value 5.
You need to overload the << operator for your class. You could also use a function to do the operator's work.
Operator <<
#include <iostream>
class Length {
friend std::ostream& operator<<(std::ostream& os, const Length& l);
public:
void setValue(float);
private:
float value_;
};
void
Length::setValue(float newValue) {
value_ = newValue;
}
std::ostream& operator<<(std::ostream& os, const Length& l)
{
os << l.value_;
return os;
}
int main() {
Length width;
width.setValue(5);
std::cout << width << std::endl; // print 5
return 0;
}
function:
#include <iostream>
class Length {
friend std::ostream& print(std::ostream &,const Length &l);
public:
void setValue(float);
private:
float value_;
};
void
Length::setValue(float newValue) {
value_ = newValue;
}
std::ostream& print(std::ostream &os, const Length &l)
{
os << l.value_;
return os;
}
int main() {
Length width;
width.setValue(5);
print(std::cout, width) << std::endl;
return 0;
}
Hello dear StackOverflowers!
I am having trouble with a template structure which comprises another (but non-template) structure.
Here's the thing:
Structure B is non-template and is defined inside a template structure A.
Strcure B is "protected" because it exists only for the purposes of structure A and no-one and nothing else shall use it outside of structure A.
There's an overload of operator<< for structure B, so that objects of type B can be sent to the standard output "cout << B_type_object;" (and it's A's friend so that it can access B which is protected).
The aforementioned printing of B objects is done only by methods defined in A (because of "2.").
As long as both structures are non-template everything works like a charm.
The moment A is a template I get an error message (provided in the code section).
Here is the working code (where A is not template):
#include <iostream>
#include <string>
struct A
{
protected:
struct B
{
std::string something;
B& operator= (const std::string&& rhs)
{
this->something = std::move(rhs);
return *this;
}
};
B B_object;
friend std::ostream& operator<< (std::ostream& output, const typename A::B& ob);
public:
void method ()
{
B_object = "This is text.";
//No error here
std::cout << B_object;
}
};
std::ostream& operator<< (std::ostream& output, const typename A::B& ob)
{
output << ob.something;
return output;
}
int main(int argc, const char * argv[])
{
A obj;
obj.method();
return 0;
}
This is the code which doesn't work
#include <iostream>
#include <string>
template <typename T>
struct A
{
T variable;
protected:
struct B
{
std::string something;
B& operator= (const std::string&& rhs)
{
this->something = std::move(rhs);
return *this;
}
};
B B_object;
template <typename X> friend std::ostream& operator<< (std::ostream& output, typename A/*<X>*/::B& ob);
public:
void method ()
{
B_object = "This is text.";
//ERROR: Invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'A<int>::B')
std::cout << B_object;
}
};
template <typename X>
std::ostream& operator<< (std::ostream& output, typename A<X>::B& ob)
{
output << ob.something;
return output;
}
int main(int argc, const char * argv[])
{
A<int> obj;
obj.method();
return 0;
}
Just declare the operator inline in B, then it works:
...
struct B
{
std::string something;
B& operator= (const std::string&& rhs)
{
this->something = std::move(rhs);
return *this;
}
friend std::ostream& operator<< (std::ostream& output, const typename A<T>::B& ob)
{
output << ob.something;
return output;
}
};
...
This has also the advantage that your are not friending any operator<< of any A<X>. In your example, the operator taking A<string>::B would also be a friend of A<int>::B. For a more in-depth explanation, see this answer:
https://stackoverflow.com/a/4661372/36565
I am learning C++, and learned that int-types are just premade classes. So I thought maybe i should try to create one.
What I want to do basically is a
normal class of int
int x;
x=7;
cout << x;
// Output is 7 on screen.
so similarly...
abc x;
x=7;
cout << x;
What would I put in
class abc{
\\ HERE!!!!!!
};
so I could do this
class SomeClass {
public:
int x;
SomeClass(int x) {
this->x = x;
}
};
int main(int argc, char *argv[]) {
SomeClass s = 5;
cout << s.x << "\n"; // 5
s = 17;
cout << s.x << "\n"; // 17
return 0;
}
But as you can see I have to use s.x to print the value - I just want to use 's'.
I am doing it as an experiment, I don't want to hear about how this method is good or bad, pointless or revolutionary, or can 't be done. I remember once I did it. But only by copying and pasting code that I didn't fully understand, and have even forgotten about.
and learned that int, types, are just premade classes
This is completely false. Still, you have complete control on how your class will behave in expressions, since you can overload (almost) any operator. What you are missing here is the usual operator<< overload that is invoked when you do:
cout<<s;
You can create it like this:
std::ostream & operator<<(std::ostream & os, const SomeClass & Right)
{
Os<<Right.x;
return Os;
}
For more information, see the FAQ about operator overloading.
the << and >> are basically function names. you need to define them for your class. same with the +, -, * and all the other operators. here is how:
http://courses.cms.caltech.edu/cs11/material/cpp/donnie/cpp-ops.html
You need to overload operator<< for your class, like so:
class abc
{
public:
abc(int x) : m_X(x) {}
private:
int m_X;
friend std::ostream& operator<<(std::ostream& stream, const abc& obj);
};
std::ostream& operator<<(std::ostream& os, const abc& obj)
{
return os << obj.m_X;
}
You don't have to friend your operator<< overload unless you want to access protected/private members.
You must define in your class abc cast operator to int and assignment operator from int, like in this template class:
template <class T>
class TypeWrapper {
public:
TypeWrapper(const T& value) : value(value) {}
TypeWrapper() {}
operator T() const { return value; }
TypeWrapper& operator (const T& value) { this->value = value; return *this; }
private:
T value;
};
int main() {
TypeWrapper<int> x;
x = 7;
cout << x << endl;
}
You want to overload the output operator:
std::ostream& operator<< (std::ostream& out, SomeClass const& value) {
// format value appropriately
return out;
}
I have several types that share common behaviour and with same constructors and operators. Some look like this:
class NumberOfFingers
{
public:
void operator=(int t) { this->value = t; }
operator int() const { return this->value; }
private:
int value;
};
NumberOfToes is identical.
Each class has different behaviour, here is an example:
std::ostream& operator<<(std::ostream &s, const NumberOfFingers &fingers)
{
s << fingers << " fingers\n";
}
std::ostream& operator<<(std::ostream &s, const NumberOfFingers &toes)
{
s << toes << " toes\n";
}
How can I minimise the duplication in the class definitions, whilst keeping class types distinct? I don't want to have NumberOfFingers and NumberOfToes derive from a common base class because I lose the constructor and operators. I would guess a good answer would involve templates.
Yes, you are correct in that it would involve templates :)
enum {FINGERS, TOES...};
...
template<unsigned Type> //maybe template<enum Type> but I havent compiled this.
class NumberOfType
{
public:
void operator=(int t) { this->value = t; }
operator int() const { return this->value; }
private:
int value;
};
...
typedef NumberOfType<FINGERS> NumberOfFinger
typedef NumberOfType<TOES> NumberOfToes
... so on and so forth.
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.