Python 3 allows overloading of *.
For example,
a*b
Allows a to define the result by providing a __mul__ method.
If however that method returns NotImplemented, the __rmul__ method on b is called (if it exists) to give the result. This is documented here.
One advantage of this is that I can make on object b that operates on a without knowing the class of a.
Is there an equivalent to __rmul__ in C++, or a way of achieving the same or a similar thing?
Correct me if I'm wrong, but according to my understanding, you need to overload an operator for 2 different classes.
You can do something like this as under:
#include <iostream>
class A
{
public:
int integer;
};
class B
{
public:
double decimal;
};
//A * B
double operator*(A a, B b)
{
return a.integer * b.decimal;
}
int main()
{
A a{12}; B b{2};
double c = a * b;
std::cout << c;
}
In the above example, I've overloaded operator* to multiply 2 objects of type A and B. But it only works for a * b, not b * a. So you can do something like this:
//B * A
double operator*(B b, A a)
{
return a.integer * b.decimal;
}
Related
STRUGGLING WITH C++ CONSTRUCTOR ARGUMENTS
So, I've just came from TS/JS/Py and trying to understand C++ concepts. But I'm struggling with using the parameter of constructor of the class FOR declaring default value for an argument. Here is the code I'm trying to run:
double Phythagorean_Hypotenuse (int& a, int& b ) {
return sqrt((a * a) + (b * b));
};
class Triangle {
public:
int a;
int b;
double c;
Triangle(int a_param, int b_param, double c_param = Phythagorean_Hypotenuse(a_param, b_param)) {
a = a_param;
b = b_param;
c = c_param;
}
};
and inside of the main function
Triangle mytri_1(10, 20);
std::cout << mytri_1.a << std:endl;
But when I try to run this code, IDE is throwing me some errors like
[Error] 'a_param' was not declared in this scope
or
[Error] call to 'Triangle::Triangle(int, int, double)' uses the default argument for parameter 3, which is not yet defined
So, please, can someone who can fix this answer the question?
Thanks.
There are some issues that prevent your code from compiling, namely:
Constructors do not have return type.
double c_param = Phythagorean_Hypotenuse(a_param, b_param) is not valid for a parameter, a_param, b_param will not be recognized.
Recommend change:
Since the result of a hypothenuse calculation will most likely be a decimal value, c should be a double.
You can do something like this:
Running sample
#include <iostream>
#include <cmath>
double Phythagorean_Hypotenuse (int& a, int& b ) {
return sqrt((a * a) + (b * b));
};
class Triangle {
public:
int a;
int b;
double c; //should be double
//initializer list is a good practice for member initialization
Triangle(int a_param, int b_param)
: a(a_param), b(b_param), c(Phythagorean_Hypotenuse(a, b)) {}
};
int main(){
Triangle mytri_1(10, 20);
std::cout << mytri_1.a << std::endl;
std::cout << mytri_1.b << std::endl;
std::cout << mytri_1.c << std::endl;
}
Output:
10
20
22.3607
As the compiler is pointing out, the other constructor arguments are not available as default parameters for the c_param argument. Rather than using default values, just overload the constructor, including one that just accepts 2 parameters. This constructor can then invoke the other constructor that accepts all 3:
// Constructor overload that accepts all 3 parameters
Triangle(int a_param, int b_param, double c_param):
a(a_param), b(b_param), c(c_param) {
}
// Constructor overload that accepts just a and b, call the other constructor
// to set all 3 members
Triangle(int a_param, int b_param):
Triangle(a_param, b_param, Phythagorean_Hypotenuse(a_param, b_param)) {
}
Default parameter values cannot reference other parameters. You can define two overloads, one of which delegates to the other, to do what you want:
class Triangle {
public:
double a;
double b;
double c;
Triangle(double a_param, double b_param, double c_param)
: a{a_param},
b{b_param},
c{c_param}
{}
Triangle(double a_param, double b_param)
: Triangle{a_param, b_param, Phythagorean_Hypotenuse(a_param, b_param)}
{}
};
Live Demo
A few other notes:
Class constructors do not have a return type. I changed void Triangle(...) to Triangle(...)
I used constructor initialization lists instead of assignment in the constructor's body. There's likely no difference for small primitive values like ints or doubles, but it's a good habit to get into and can make a big difference for more complex types
int doesn't make sense for the type of c (or a or b for that matter). The sides of a triangle are unlikely to all be integers
There's no reason to pass parameters to Pythagorean_Hypotenuse by reference. It's simpler and likely faster to pass them by value
I have two classes, lets call them A and B. And I overloaded operator+= in class A. Now I want to do something like this:
A += B + B + B
And class B doesn't have overloaded operator+, which is a problem because the evaluation is right to left (it wants to add all Bs and then += the result to A).
Is there any way to achieve my goal without actually overloading operator+ for class B?
Is there any way to achieve my goal without actually overloading operator+ for class B?
In a word, no.
A::operator+= takes a B as input, so if you want A += B + B + B to work, you need a way of adding B objects together to produce a new B that += can take as input, and that is exactly what operator+ is meant for.
This is possible.
Instead of overloading the addition operator, you can make B implicitly convertible to and from an arithmetic type. A demo that requires no overloading of operator+ for B as per requirement, yet allows the exact expression that you desire:
struct B {
B() = default;
// this constructor makes B convertible from int
B(int){}
// this operator makes B convertible to int
operator int() {
return 42;
}
};
struct A {
A& operator+=(const B&) {
return *this;
}
// alternative:
// if you use this, then B does not need to convert from int
// A& operator+=(int)
};
int main() {
A A;
B B;
A += B + B + B;
}
So, I'm fairly new to C++ but I have done lots of C programming. Partly as an exercise, and also partly because I don't have a matrix package that permits the fine-grained control over things that I would like, I have been writing my own matrix class mtMatrix and overloading various operators to let me write equations conveniently. I've overloaded +,-,/, and * to perform element-wise arithmetic operations, after checking that the matrices are of the same size, while full-on matrix multiplication is done by the class method Mult(). I've further overloaded +,-,/, and * to multiply matrices by scalars, so I can have a mtMatrix M and write "mtMatrix T = M * 2.0" to get a new matrix whose entries are twice as large as the old one. However, when I try to write "mtMatrix T = 2.0 * M" I run into problems, and I'm not sure how I would write the overloading for +,-, and * to accomplish this, even though what I would want is precisely the same result as if I were to type "mtMatrix T = M * 2.0." It seems that the contents of the overloading function would be identical in the two cases, but the signature of the function would be different. Can anyone point me in the right direction?
You need to create an operator associated with an lvalue as int. The operator* you have declared in your class has as lvalue 'this' therefore M*2.0 works.
In order to create an operator associated as lvalue for int you need to declare it outside the class, and if the operator has as rvalue an object of your class then you need to declare it as friend so it can access the private values.
Below is an example, where the class in not a matrix but simulates the behavior you want to accomplish.
#include <iostream>
class M
{
int value_;
public:
M(int value):value_(value){}
int& operator()() { return this->value_; }
int operator()() const { return this->value_; }
int operator*(int value) { return this->value_ * value; }
friend int operator*(int, const M&) ; //so it can access the M private objects
};
int operator*(int value, const M& other)
{
return value * other.value_;
}
int main()
{
M m0(10);
M m1(5);
m0() = m0() * 10;
std::cout << m0() << std::endl;
m0() = 10 * m1();
std::cout << m0() << std::endl;
return 0;
}
Suppose I have a wrapper class for a numerical value with some "extra functions":
struct DblWrapper{
double value;
void func1(); // maybe to print nicely
void func2(); // maybe to register this for automatic capture at data source
}
Now, I'd also like to use instances of this wrapper as convenient as possible in numerical expressions, something like:
DblWrapper a;
DblWrapper b;
DblWrapper d;
double c = a * b; // Best idea: overload operator () ( c = a() * b() )
d = c; // Best idea: overload operator =
Or would there actually be a way for fully-automatic conversion to the numerical value as given in the c = a * b example?
Write conversion operator and conversion constructor.
operator double() const
{
return value;
}
DblWrapper(double d) : value(d)
{
}
Live example
I have two classes, ClassA and ClassB.
ClassA has three methods:
double Foo(double, ClassB);
double Bar(double (*f)(double));
double Baz(double, ClassB);
I would like to define a function Qux inside Foo, based on Baz but without the argument of type ClassB: i.e. of the kind "double Qux(double)" so that I can pass it to Bar:
double ClassA::Foo(double x, ClassB y)
{
// double Qux(double .) = Baz(., y)
Bar((*Qux))
}
Does some one have any idea?
I guess some will answer this is not the good way to do it. So just to explain the concrete situation, I am pricing financial assets using a numerical method (http://en.wikipedia.org/wiki/Simpson%27s_rule) in order to compute integrals:
ClassA: FinancialAsset
ClassB: PrincingModel
Foo: FinancialAsset.Price(date, PrincingModel)
Bar: FinancialAsset.SimpsonMethod(FunctionOneArgument)
Baz: FinancialAsset.FunctionTwoArguments(date, PrincingModel)
And I am looking for:
Qux: FunctionOneArgument(date) = FinancialAsset.FunctionTwoArguments(date, PrincingModel)
I am not sure what is the good way to address this structure. I you have a better / more c++'s way to do it, I'll take :)
Thanks
You can't do that exactly, because your Bar function is taking a pointer to a regular function, but you can use this instead:
class A {
...
public:
double Foo(double, ClassB);
double Bar(std::function<double(double)> f);
double Baz(double, ClassB);
};
double ClassA::Foo(double x, ClassB y)
{
auto Qux = [&](double x) { Baz(x,y); };
return Bar(Qux);
}
std::function is a more general way of representing function-like objects. You can convert a regular function, a lambda, or a function object to it.
Depending on whether you have C++11 or not, you either want std::bind and std::function or boost::bind and boost::function for older C++ versions.
binding allows you to take a function and bind 0 or more of the parameters, or rearrange the parameters. Indeed something you have above would look like this:
double ClassA::Foo(double x, ClassB y)
{
boost::function<double> baz = boost::bind(this, ClassA::Baz, _1, y);
Bar(baz);
}
And Bar's signature would take a boost::function instead of a function pointer.
Note my syntax might be slightly off for binding memeber functions, have a look at the documentation for details.
see here:
http://www.boost.org/doc/libs/1_53_0/libs/bind/bind.html
Or here: http://en.cppreference.com/w/cpp/utility/functional/bind
You can do it without changing any function signatures (and C++11 or boost), but I wouldn't suggest it if you can avoid it. It's ugly, not thread-safe, and in general not very nice:
#include <iostream>
struct B
{
// some data in B
int i;
};
struct A
{
//some data in A
double d;
// the functions you defined in A
double Foo(double x, B y);
double Bar(double (*f)(double));
double Baz(double x, B y);
};
// a poor substitutes for closures
struct
{
A *a;
B *b;
} hack;
double Qux(double x2)
{
// use the stored pointer to call Baz on x2
return hack.a->Baz(x2, *hack.b);
}
double A::Foo(double x, B y)
{
// store pointers for use in Qux
hack.a = this;
hack.b = &y;
// do something with x
d += x;
double result = Bar(&Qux);
return result;
}
double A::Bar(double (*f)(double))
{
// do something with d, call the passed function
d += 1;
return f(d);
}
double A::Baz(double x, B y)
{
// do something with the passed data
return x + y.i;
}
int main()
{
A a;
a.d = 1.25;
B b;
b.i = 2;
std::cout << a.Foo(.25, b) << std::endl; // should be 4.5
return 0;
}