I'm writing my class now and testing it. It seems that the comma operator (operator,) refuses to work, the program simply skips it. This is the code I'm running
fileObj << buffer,40;
I wrote the following operators (only prototypes shown, the code isn't relevant):
const file_t& operator<<(const void* buffer);
void operator,(int length);
the "operator<<" works fine, the program uses it but when it arrives to the "operator," , it simply skips it like it doesn't even exist. Needless to say that both operators depend on each other.
Any idea why the comma operator is being skipped? Thanks.
Your << operator returns a const file_t reference. Your comma operator is a non-const function. Since the types don't match, the compiler does not select your comma operator to perform the operation. Instead, it uses the built-in comma operator, which simply evaluates both operands and returns the right one. (And since evaluation of the right operand has no side effects in your example, it appears as though it's not called at all.)
If your comma operator doesn't modify the object it's called on, then make it const:
void operator,(int length) const;
If the operator needs to modify your object, then don't return a const object from your << operator:
file_t& operator<<(void const* buffer);
Related
I am having trouble trying to understand why someone would want to overload an operator. I understand it can help reassign functionality, but it takes away key functionalities as well.
In an assignment given to me, I was given a skeleton code that Vector4f overloaded =, and now in Matrix4f.h, I can't use = when creating a function to turn a matrix into an identity matrix (the matrix is set to a float, not int).
Is the original functionality lost, or do I need to type cast the = somehow? Also, why is even reassigning core functionality operators a good idea? My professor had suggested that we could have done add() and overloaded that, but didn't.
Operator overloading is a way of adding some syntactic sugar to help your types have a full, semantically-coherent API.
Take, for example, std::string. In terms of pure assignment operators, it provides a number of ways to help the string behave in a coherent and semantically-sound way. In addition to the copy/move operator= overloads, it supplies:
operator=(CharT): Assign to a character
operator=(const CharT*): Assign to a string-literal or pointer to C-style string
Which allow it to behave in a way that the consumer would expect, such as:
auto str = std::string{""};
str = "hello world"; // c-style string/string literal
str = 'c';
Other operators in this example would be:
operator+(const CharT*): append c-strings/string literals
operator+(CharT): append characters
operator+(const basic_string&): append other std::strings
Equality or comparison operators (operator==, operator<, etc): comparing things in a coherent way
Adding operators doesn't remove functionality. It helps to extend the functionality by providing a semantically clear way of writing code.
Note: The assignment operator is a special case, in that some circumstances may result in the compiler-generated operator= to be deleted. However, you can always define it by-hand, or explicitly use the = default syntax to re-enable it. For example:
class Foo
{
public:
...
Foo& operator=(const Foo&) = default; // Explicitly ask for the compiler-generated one
};
Languages that do not support operators like this may result in having to write code with everything written out. For example:
string("hello").append(' ').append("world")
instead of simply
std::string{"hello"} + ' ' + "world";
(these are contrived examples)
Edit: The answer above focuses more on your immediate question as to why to overload operators. Your error, as seen in your screenshot, appears to be due to a lacking operator= overload for assigning an int (or some other numerically convertible type, like a float) to the Vector4f type. Defining a custom operator would enable this.
I am writing some C++ code that needs to test string and character equality, and for the sake of simplicity I'd like to consider the n-dash (0x96) and m-dash (0x97) characters to be identical.
My first instinct was to redefine the equality operator, and started to code, but then ran into a problem:
inline bool operator==(char lhs, char rhs) {
if (lhs == 0x96 && rhs == 0x97) return true; // works fine
else if (lhs == 0x97 && rhs == 0x96) return true; // works fine
else return lhs == rhs; // infinite recursion...
}
In the final line of that function, ideally I'd like to be able to call 'old' form of the equality operator, similar to how a derived class is able to call a base class' version of a function.
I am wondering if this is possible in C++? If not, I'm assuming I should just extract the above code into a separate function and call the function rather than using the operator.
You can't. Once you overload an operator, you replace the default one. (There is an interesting exception: namely std::addressof can be used to circumvent an overloaded & operator).
I'd have strong reservations about overloading operator==(char, char): you'll break a lot of code.
If you really must do it though, you could always write (int)lhs == rhs; which will cause conversion of both operators to int so blocking the recursion. Since int is a superset of char, this will always be defined. Oddly enough, that's why your two prior comparisons work: an implicit conversion of char is taking place which stops the function from calling itself.
First of all, never attempt to overload operators purely on builtin types... Use a function instead...
Your first comparison statements worked because of type promotion
char will be converted to an int and comparisons will be made... the last one calls your operator again
This feels like too basic a question to not have asked already so if it's already out there I'd accept the link as the answer or delete this post if you fellas see fit, personally I couldn't find it anywhere at least so perhaps this'll be useful to others...
So yeah, like it's said in the title, how do I make operators that'd let me work from the left side of the object? f.e:
++obj
variable * obj
etc
If I wanted to work on the right side of that 'obj' I'd make something like
obj operator*(const variable &t){...} //for obj * variable operation
intuitively I tried
obj *operator(const variable &t){...} //for variable * obj operation(?)
to make it work the other way around but of course, that didn't work, any suggestions?
Ummm you cannot do that. I mean, choose which side the operator works on. It is defined by the standard. The operators in c++ do not have sides they operate on. All are different operators. The operator you overload is defined by the signature.
The "side" has meaning only for the unary operators anyway. For binary operators it is either a member function called on the left operand, with right operand passed as an argument, or a free standing function.
The case that "allows definition of the side" is ++ and --. And it is a special case. ++c and c++ are actually two different operators in terms of language -- pre- and post- incrementation. The differentiation between realized by a "bogus" parameter in the overload: http://en.cppreference.com/w/cpp/language/operator_incdec.
There are other unary operators too, and you cannot choose side E.g: !, ~, there are no suitable overloads defined for "right side" cases.
Other disambiguation is also done via parameters. * used for both, member access and arithmetic operation. The operator which you overload is defined by number of parameters.
T T::operator*(const T2 &b) const; is artithmetic one, and R& T::operator*(); is member access.
Here you can find rules for all operators: http://en.cppreference.com/w/cpp/language/operators.
Aaand since its c++ you can abuse it. Unrecommended though.
You can overload function and make that function friend of the class.
variable operator*(const variable &, const variable *);
class variable {
friend variable operator*(const variable &, const variable *);
};
This question may have been asked before, but I wasn't quite sure what to search for - at least in regard to what terms to search for.
In any case, this is my problem. Consider this code snippet:
int main()
{
myArray list_Array(10);
int i;
cout << "list_Array : ";
for (i = 0 ; i < 10; i++)
cout << list_Array[i] <<" ";
cout<< endl;
...
Here, myArray class is really just an array with extra safeguards such as bound checking. Here, the << operator is overloaded in addition to the [] operator being overloaded. I've already overloaded the latter operator, and I started writing the implementation to overload <<.
However, I started wondering how isStream will interpret this part of the expression: list_Array[i].
To explain, I could typically overload this operator with something like this:
ostream& operator<< (ostream& isObject, someObject& x)
{
isObject << x.length;
return isObject;
}
In this case, what I'm passing is not purely the object itself. Instead, I'm wanting to print list_Array[i].
For sake of detail, this is the overall functionality of that overload:
const int& myArray::operator[](int index) const
{
return list[index];
}
That said, how is this expression handled? Which overload will be applied first? If the overloaded << operator is applied first, do I need to modify the parameter I'm passing into the << implementation?
Any constructive input is appreciated.
NOTE: list is a dynamic array.
That said, how is this expression handled? Which overload will be applied first? If the overloaded << operator is applied first, do I need to modify the parameter I'm passing into the << implementation?
This has nothing to do with overloading. It's operator precedence, and it doesn't change whether your operators are overloaded or not.
[] goes first, and the result is passed to your overloaded << operator. This is true regardless of overloading; the operands of an operator can't affect its precedence.
Obviously, the << operator is overloaded in addition to the [] operator being overloaded
That's not obvious at all. You would only need to overload << if your array contains some kind of object that ostreams don't already have an operator<< for. Your overloaded [] appears to return ints, so there is absolutely no reason write your own << operator for working with ostream.
In this case, what I'm passing is not purely the object itself. Instead, I'm wanting to print list_Array[i], which is an operation on my object.
You're not "printing an operation". The operation happens, independent of the printing, and the result of the operation is passed to your <<. The result would be the int returned by your operator[].
I could use some help understanding the following in C++, particularly the difference between an operator and a function:
What is an operator?
What is a function?
What is the difference between them?
Is a user-defined operator+() a function or an operator?
Can an operator operate on operands at compile-time? Do they always operate at compile time? (like sizeof() in C++)
An operator is a symbol like +, -, += and so forth (see 13.5). They don't carry a meaning. During semantic analysis, the meaning of an operator is determined.
A function is a constructor, destructor, conversion function (that looks like operator type()) or operator function (function template specialization and instantiation can yield these in turn).
An operator function is something that implements an operator (see 13.5). An example is operator+. These are functions in all respects, and the only difference to "usual" functions is that they may be called implicitly and they have a funny name.
Some operators have a built-in meaning, that can be changed by the programmer. One refers to the built-in meaning of an operator simply by saying built-in operator (see 5/3). However, if such an operator is applied on operands for which a built-in meaning is defined, changing that meaning is only allowed for a few cases (these are assignment, address-of and the comma operator, see 13.5/6).
What is an operator?
An operator is a symbol that is use in expressions.
Examples are: + - * / etc
On built-in types there operations are well defined and unchangable.
For user defined types the operators can be defined as syntactic sugar for a function/method call
Array a;
a = b + c; // a.operator=(b.operator+(c));
What is a function?
We use the term function/method interchangeably most of the time. The only difference is that a method is associated with an instance of a class object. Otherwise they are the same. They provide a way of grouping a set of instructions together.
What is the difference between them?
The action of an operator on a built-in type is defined by the compiler.
The action of an operator on a user defined type is a function call.
Is a user-defined operator+() a function or an operator?
Its a function (or a method). Use of an operator on a user defined type is syntactic sugar for a function call. They are still refereed to as operators though in normal conversation.
Can an operator operate on operands at compile-time?
For built-in types yes. The compiler has extensive ability to optimize there usage.
For user defined types. It can perform optimizations on the operators just like other functions which may lead to there being eliminated, but the code is not executed at compile time.
Do they always operate at compile time? (like sizeof() in C++)
No. sizeof() is relatively unique.
Edit:
To show that operator in user defined class behave just like functions here is an example of using mem_fun_ref
#include <vector>
#include <algorithm>
#include <memory>
#include <functional>
class X
{
public:
// Non standard operators.
// Because std::mem_fun_ref has a known weakness in that it can
// not be used with methods that take parameters be reference.
//
// The principle is the same though. That the operator+ can be
// used anywhere that the add() method can be used.
X& operator+(X* rhs) { return *this;}
X& add(X* rhs) { return *this;}
};
typedef X& (X::*MEMF)(X* rhs);
int main()
{
MEMF p1 = &X::add;
MEMF p2 = &X::operator+;
X value;
std::vector<X> data;
std::for_each(data.begin(),
data.end(),
std::bind2nd(std::mem_fun_ref(&X::operator+),&value));
}
There is no meaningful difference between operators and functions, except that operators have a different syntax. Primitive operators however are not functions.
What is operator?
An operator is generally an operation performed on a variable given some form of punctuation. For example, the default behavior of operator+ between two integers is to add them.
What is function?
A function is a subroutine -- a reuseable block of code.
What is the difference between them?
Nothing, as far as user code is concerned, except for syntax. Note that if you override operator||, operator&&, or (to a lesser extent) operator,, you change the semantics of the built in operator semantics. In the case of && and ||, you make the operation which is normally short circuiting into an operation which is not. In the case of the comma, you would need to ensure that you evaluate the arguments left to right, as the comma operator normally behaves in this way.
Is user-defined operator+() a function or operator?
Neither. It is a user defined operator overload. A function name cannot start with the keyword operator, and an operator is simply the actual punctuation mark used to invoke the operator overload, i.e. + or -. EDIT: Note that while technically speaking it is not a function, it does have the semantics of a function call, as demonstrated in #Martin York's excellent answer.
Can operator operate on operands at compile-time? Do they always operate at compile time? (like sizeof() in C++)
No, sizeof cannot be overloaded. If you want some form of compile time operation done, you need to use something like template metaprogramming. Note that if the compiler is able to do the calculation at compile time it may elide the call into your overloaded operator, of course.
In C++ you can override what the symbols +, -, ==, etc. do when applied to class instances. By defining the "operator+" method in class A, you are telling the compiler what to do with code like:
A a, b, c;
c = a + b; // the + here actually calls a.operator+(b)
It's also a function or more precisely an instance method, in the sense that it's something that gets called.
EDIT: see also http://en.wikipedia.org/wiki/Operator_overloading
and http://en.wikibooks.org/wiki/C++_Programming/Operators/Operator_Overloading
There is no huge difference between functions and operators. You can think of an using operator, e.g., 'a+b', as a shortcut to the function operator+(a,b) which is defined for the types of a and b. Of course, operators on primitive types (like integers) and a few other exceptions are not necessarily defined like this.
Thus, to answer a few of your specific questions:
Is user-defined operator+() a function or operator?
A function that implements an operator.
Can operator operate on operands at compile-time? Do they always operate at compile time?
Since it is a function, it operates at run time, but in some cases compiler optimizations can do work at compile time for certain operators. I'm not 100% sure why you're asking this, so perhaps there is something I'm not aware of here.
There are only two minor differences between functions and operators.
Operators can be used in two ways (x+y or operator+(a,b)).
Operators must have same number of parameters as the built-in one (operator== must have exactly two params). The exception from this rule is function call operator() which can be overloaded with any number of any parameters.
Here are some differences between an operator and a function:
An operator does not push its parameters onto the stack, but a function pushes its parameters onto the stack.
The compiler knows about the operation of the operators, but is not aware of the output of the function. Said a different way, the action of the operator is defined at compilation time and that of a function is defined at the runtime.