I am wondering if I could write, for instance: <<(object, cout); or <<(cout,object); where object is a user defined class which has the << operator overloaded, just as one could write:
int a = +(2,3); and obtain the expected result, as in int a = 2 + 3;.
Furthermore, what should one do if this is possible, but requires a few steps? Should one overload the << operator with two different signatures?
just as one could write: int a = +(2,3); and obtain the expected
result, as in int a = 2 + 3;
No, you have a misunderstanding. +(2, 3) will go by the associativity of the comma operator and assign +3 (3) to the variable a.
Therefore, int a = +(2, 3) is the same as int a = 3, and not int a = 2 + 3
I am wondering if I could write, for instance: <<(object, cout); or
<<(cout,object);
No, you can't.
If you want to use the operators in that fashion then you should call its fully qualified name, for example:
operator+ instead of +
operator<< instead of <<
Note:
This will not work for fundamental datatypes. Take care of the class scope and namespaces when you are using the overloaded versions of these operators.
You can do this, e.g.
operator<<(std::cout, "hi");
This expression
int a = +(2, 3);
is not doing operator+. It's first applying the , sequence operator, which gives 3, and then applying unary +, which gives 3.
You can't do this
int a = operator+(2, 3); // error
because ints are fundamental types.
If you have user defined types S, then the following snippets have the same meaning
S s{};
std::cout << s;
auto x = s + s;
is the same as
S s{};
operator<<(std::cout, s);
auto x = operator+(s, s);
assuming the operators are defined for S, the correct operator will be called.
Related
for the expression
(func1() * func2()) + func3()
will func1() * func2() be evaluated first as it has brackets or can the functions be called in any order like
first func3() and then (func1() * func2())
The functions can be called in any order.
Precedence of operators has got nothing to do anything with the order of evaluation of operands.
The C or C++ Standard doesn't determine the order in which the functions would be called. .
The order of evaluation of subexpressions, including
the arguments of a function call and
operands of operators (e.g., +, -, =, * , /), with the exception of:
the binary logical operators (&& and ||),
the ternary conditional operator (?:), and
the comma operator (,)
is Unspecified
For example
int Hello()
{
return printf("Hello"); /* printf() returns the number of
characters successfully printed by it
*/
}
int World()
{
return printf("World !");
}
int main()
{
int a = Hello() + World(); //might print Hello World! or World! Hello
/** ^
|
Functions can be called in either order
**/
return 0;
}
You can't make any assumptions about the order in which these functions will be called. It's perfectly valid for the compiler to call these functions in any order, assign the results to temporaries, and then use these temporary values to calculate the result of the expression.
These calls can be made in any order. You want to learn about C++ sequence points C++ sequence points.
Parenthesis in C/C++ force order of operations. func1() * func2() will be added to func3(), but the compiler can choose to call the functions in whatever order it wishes before passing in the results to the multiplication / addition operation.
It's natural to think that A+B is evaluated before C in this psudocode:
(A+b)*C
But in fact this is not so. The Standard says that the order of evaluation for all expressions is "Unspecified", unless otherwise specified by the Standard:
5/4 [expr]:
Except where noted, the order of
evaluation of operands of individual
operators and subexpressions of
individual expressions, and the order
in which side effects take place, is
unspecified
The Standard then goes on to identify a parenthesized expression as a "Primary expression" but does not specify the order of evaluation for Primary expressions. (5.1/5).
In Standardese, "Unspecified" does not mean "Undefined." Rather it means "Implementation Defined, but no documentation is required." So you might not even be able to say what the order of evaluation is for a specific compiler.
Here is a simple program illustrating the behavior:
#include <iostream>
#include <string>
using namespace std;
class Foo
{
public:
Foo(const string& name) : name_(name) {++i_; cout << "'" << name << "'(" << i_ << ")\n"; };
operator unsigned() const { return i_; }
Foo operator+(const Foo& rhs) const { string new_name = name_; new_name += "+"; new_name += rhs.name_; return Foo(new_name); }
private:
string name_;
static unsigned i_;
};
unsigned Foo::i_ = 0;
int main()
{
(Foo("A") + Foo("B")) + Foo("C");
}
On my MSVC10 running in Debug/x64 on Win7, the output happened to be:
'C'(1)
'B'(2)
'A'(3)
'A+B'(4)
'A+B+C'(5)
I have following C++ code snippet :
inline std::vector<std::unique_ptr<xir::Tensor>> cloneTensorBuffer(
const std::vector<const xir::Tensor*>& tensors)
{
auto ret = std::vector<std::unique_ptr<xir::Tensor>>{};
auto type = +::DataType::XINT;
ret.reserve(tensors.size());
for (const auto& tensor : tensors) {
ret.push_back(std::unique_ptr<xir::Tensor>(xir::Tensor::create(
tensor->get_name(), tensor->get_shape(), xir::DataType{type, 8u})));
}
return ret;
}
I am not clear about the statement:
auto type = +::DataType::XINT;
What is meant by + followed by ::(scope resolution operator)?
The combination has no special meaning. + is the regular prefix operator. In this particular case it’s probably redundant, or performs coercion to int. However, the actual meaning might differ depending on how it’s overloaded for the type of ::DataType::XINT.
And :: is regular scope resolution operator. When used at the beginning of a sub-expression (i.e. without a left-hand operand), it causes lookup to be performed at the top scope, i.e. it ignores any shadowing redefinition of DataType in a nested scope:
int x = 1;
void f() {
int x = 2;
std::cout << "inner = " << x << "\n"; // inner = 2
std::cout << "outer = " << ::x << "\n"; // outer = 1
}
There is no +::. Its the unary + operator and :: operator.
::foo refers to foo in the global namespace. It might be necessary when there is another DataTye::XINT in the current namespace.
The unary + is sometimes used to trigger implicit conversions. You need to check what type ::DataType::XINT is and what conversions it has available.
As I don't know what ::DataType::XINT is, here is an example with a lambda expression:
template <typename T>
void foo();
int main() {
auto x = [](){};
foo(x);
foo(+x);
}
Error message (shortened) is:
<source>:6:8: error: no matching function for call to 'foo(main()::<lambda()>&)'
6 | foo(x);
<source>:7:8: error: no matching function for call to 'foo(void (*)())'
7 | foo(+x);
| ~~~^~~~
You can see that foo(x) tries to call foo with the lambda, while in foo(+x) the lambda was implicitly converted to a function pointer (because of ClosureType::operator ret(*)(params)() and + being available for function pointers but not for the lambdas type).
I am fairly new to C++ and I have been reading and writing some of my own code. I see these operators from time to time, if that is even the right word to use?
+= // Not sure what it means
So my question is: what do they mean/do, and what are they called?
For further reference, I'd like to know what they are called so I can easily look it up (searching simply for "+=" for instance yielded nothing).
Edit: For anyone else who does not know the meaning (or in my case knew the name of these) I found this Wikipedia link which might come of handy to other people: http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
Yes, these are operators. More specifically, they are known as compound assignment operators. Here's the full list of them:
*= /= %= += -= >>= <<= &= ^= |=
They are defined like so:
The behavior of an expression of the form E1 op = E2 is equivalent to E1 = E1 op E2 except that E1 is evaluated only once.
So x += 5; is almost the same as x = x + 5;.
You can think of it as a modifying addition. If you just do x + 5, the result of the expression is what you get if you add x and 5 together, but x hasn't changed. If you do x += 5;, x actually has 5 added to its value.
its just an abbreviation:
a+=2; means a=a+2;
of course as many operators: you can overload it to give it alternative meaning, ans actually we do it often to provide meaning for example in the case what it means to add int to our class SomeClass:
SomeClass s;
s+=1; //operator+=(SomeClass& s, int i){} is used here
class A{
public:
A():i_(123){}
~A(){}
int i(){return i_;}
A const& operator+=(int i){
std::cout<<"operator+=";
this->i_=i_+i;
}
private:
int i_;
};
int main(int argc, char** argv) {
A a1;
a1+=3;
std::cout<<a1.i();
return OK;
}
output: operator+=126
I copied this program from a c++ practice book. What's going on behind the scenes?
The expected output is:
sum=30 sum=70
#include<iostream>
using namespace std;
class M
{
int x;
int y;
public:
void set_xy(int a, int b)
{
x=a;
y=b;
}
friend int sum(M m);
};
int sum (M m);
//so far so good, problem begins from here. what's happening after here?
{
int M ::*px = &M ::x;
int M ::*py = &M ::y;
M *pm =&m;
int s= m.*px+ pm->*py;
return s;
}
int main()
{
M n;
void (M :: *pf)(int, int) = &M ::set_xy;
(n.*pf)(10, 20);
cout <<"sum=" << sum(n) << endl;
M *op= &n;
(op-> *pf)(30,40);
cout << "sum=" << sum(n)<< endl;
cin.ignore();
getchar();
return 0;
}
The problem is because of extra whitespace at op-> *pf:
(op->*pf)(30,40); // ok
I think #fefe has probably said the reason in comment. ->* is a single operator, similar to .*. So, if those 2 are separated, then it will result in different syntax, which gives compiler error.
Take a look at Pointer to class data. And for the error, ->* is an operator, you can't put a space between them.
iammilind bet me to the error; op-> *pf must be changed so that you have ->* together as a single operator - a pointer to member operator (couldn't find a better link). The whitespace in op ->* pf is perfectly valid.
That's the same for something like i++; ++ is a single operator and will cause an error if you try and have i+ +.
Now for what it's doing. The example is of a pointer to a member function. pf is being declared as a member function of class M, that takes two int arguments with a void return type. It's being initialized to point to the M::set_xy function.
Inside main:
n is of type M, therefore in order to use pf to call set_xy of n you'd use the .* operator: (n.*pf)(10, 20);. That's equivalent to n.set_xy(10, 20);.
Since op is of type M* (a pointer to an M object), you'll need to use the ->* operator and call the function pointed to by pf as: (op->*pf)(30, 40);, which is equivalent to op->set_xy(30, 40);
Inside sum:
The examples are simply of pointers to member/instance variables, as opposed to member functions. It's simply demonstrating how you would add together m.x and m.y using those types of pointers.
for the expression
(func1() * func2()) + func3()
will func1() * func2() be evaluated first as it has brackets or can the functions be called in any order like
first func3() and then (func1() * func2())
The functions can be called in any order.
Precedence of operators has got nothing to do anything with the order of evaluation of operands.
The C or C++ Standard doesn't determine the order in which the functions would be called. .
The order of evaluation of subexpressions, including
the arguments of a function call and
operands of operators (e.g., +, -, =, * , /), with the exception of:
the binary logical operators (&& and ||),
the ternary conditional operator (?:), and
the comma operator (,)
is Unspecified
For example
int Hello()
{
return printf("Hello"); /* printf() returns the number of
characters successfully printed by it
*/
}
int World()
{
return printf("World !");
}
int main()
{
int a = Hello() + World(); //might print Hello World! or World! Hello
/** ^
|
Functions can be called in either order
**/
return 0;
}
You can't make any assumptions about the order in which these functions will be called. It's perfectly valid for the compiler to call these functions in any order, assign the results to temporaries, and then use these temporary values to calculate the result of the expression.
These calls can be made in any order. You want to learn about C++ sequence points C++ sequence points.
Parenthesis in C/C++ force order of operations. func1() * func2() will be added to func3(), but the compiler can choose to call the functions in whatever order it wishes before passing in the results to the multiplication / addition operation.
It's natural to think that A+B is evaluated before C in this psudocode:
(A+b)*C
But in fact this is not so. The Standard says that the order of evaluation for all expressions is "Unspecified", unless otherwise specified by the Standard:
5/4 [expr]:
Except where noted, the order of
evaluation of operands of individual
operators and subexpressions of
individual expressions, and the order
in which side effects take place, is
unspecified
The Standard then goes on to identify a parenthesized expression as a "Primary expression" but does not specify the order of evaluation for Primary expressions. (5.1/5).
In Standardese, "Unspecified" does not mean "Undefined." Rather it means "Implementation Defined, but no documentation is required." So you might not even be able to say what the order of evaluation is for a specific compiler.
Here is a simple program illustrating the behavior:
#include <iostream>
#include <string>
using namespace std;
class Foo
{
public:
Foo(const string& name) : name_(name) {++i_; cout << "'" << name << "'(" << i_ << ")\n"; };
operator unsigned() const { return i_; }
Foo operator+(const Foo& rhs) const { string new_name = name_; new_name += "+"; new_name += rhs.name_; return Foo(new_name); }
private:
string name_;
static unsigned i_;
};
unsigned Foo::i_ = 0;
int main()
{
(Foo("A") + Foo("B")) + Foo("C");
}
On my MSVC10 running in Debug/x64 on Win7, the output happened to be:
'C'(1)
'B'(2)
'A'(3)
'A+B'(4)
'A+B+C'(5)