Type conversions to custom class - C++ - c++

I have a class of complex numbers, loaded the +, -, *, /,=,!= operators both with complex and double types on both ways but when I write the code complex z = 1, the compilers gives me an error saying that there are no variable conversion from int to complex. Although, it accepts the code
complex z;
z = 1;
and everything works fine. How can I fix this error?

The line complex z = 1 does Copy Initialization. You'll need an appropriate constructor:
complex::complex(int i) // or double or whatever is convertible to int by
{ // implicit conversion
// your code
}
This is different than
complex z;
z = 1;
which is assignment (to a previously default constructed object) that requires an assignment operator.

You may want add a constructor which accepts a double:
class complex
{
public:
complex(double d) : _real(d), _imag(0) { }
...
};
Be careful, though: this will make it possibly to pass an int wherever a complex is expected, because your constructor will perform an implicit conversion.

You need to write an appropriate constructor.
class complex {
public:
complex(double x) {
// ...
}
// ...
};

You need a constructor that takes a double.
class complex
{
public:
complex( double d );
};

Related

C++ use of explicit suggested by cppcheck

Is using the cast constructor bad?
Otherweise why a code quality checker (cppcheck in my case) would constantly suggest to add explicit before single parameter constructors?
What if I want to do
class MyClass {
A(int) {}
};
A a = 1;
If I follow the "suggestions" and write
class MyClass {
explicit A(int) {}
};
A a = 1;
would throw an error, but if I use the first I'll have a warning that i've to document to pass the code reviews.
C++ Core Guidelines
C.46: By default, declare single-argument constructors explicit
Reason
To avoid unintended conversions.
Example, bad
class String {
public:
String(int); // BAD
// ...
};
String s = 10; // surprise: string of size 10
Exception
If you really want an implicit conversion from the constructor
argument type to the class type, don't use explicit:
class Complex {
public:
Complex(double d); // OK: we want a conversion from d to {d, 0}
// ...
};
Complex z = 10.7; // unsurprising conversion
See also: Discussion of implicit conversions
Such implicit class type conversion can be used easily without intention. With this converting constructor every function or member function which accepts MyClass as argument will accept also int. Therefore every int passed to such a function will be converted to a temporary MyClass which will be discarded after the function has finished. Probably not what you want.

C++ std::maps and class values with constructors

It's been a long time since I've seen C++ -- 30 years of more, and obviously, things have changed a lot. I'm also spoiled with Scala, Julia etc, which take care of this magic under the covers, but... no more.... I'm tryihng to figure out why this doesn't work:
class Foo {
uint_fast8_t val1;
std::string name;
uint_fast16_t val2;
};
std::map<std::string, Foo> myMap;
myMap["Test"] = { 1, "Test2", 2 };
This fails to compile because several operators need to be overloaded for map to work. Note, this happens evne with a constructor defined such as
Foo(uint_fast8_t v1, std::string s, uint_Fast16_t v2) { };
If I just do a
myMap["Test"] = Foo()
This works because the constructor has the expected number of arguments (0) as opposed to 3. It's probably basic, and I'm sure I'm showing how long it's been, but what did I miss?
All the members of a class are by default private in contrast to struct where all the members are by default public so default value initialization of the member variables in a class via list initializer is not allowed.
Kindly refer this link for better understanding.
Hope this helps you
You have a class with default constructor,which takes zero arguments.
And you are trying to create he inline object with passing the three arguments.
I will suggest to add the parameterized constructor.
class Point {
private:
int x, y;
public:
// Parameterized Constructor
Point(int x1, int y1)
{
x = x1;
y = y1;
}
...
};
// Constructor called
Point p1(10, 15);
Basic C++ constructor types can be checked at link

Conversion constructor between classes c++

The background: I am reading a wonderful book, where they briefly mentioned conversion constructors.
Though I understand fundamentals of the conversion constructors, I was a bit lost, when in practice problems section they asked:
Write a conversion constractor that converts ratnum into realnum from the code that I received prior to the problem:
class ratnum {
int num, denom;
public:
ratnum(int numenator = 2, int denominator = 3) : num(numenator), denom(denominator) {}
void show() { cout << static_cast<double>(num) / denom << endl; }
double result() { return num / denom; }
};
class realnum {
int number;
public:
realnum(double numr = 0) : number (numr) {}
};
I always dealt with the conversion constructors as such:
ratnum one = 10; //or
ratnum two = {10, 2}
But never saw that we can convert from class to a class type.
Could you, please, say how such conversion constructor should work (maybe with example)?
Is defining a function result of the ratnum class and writing:
realnum check = one.result();
is what is meant here?
But never saw that we can convert from class to a class type. Could
you, please, say how such conversion constructor should work (maybe
with example)?
It's exactly the same as converting from a non-class type. There's literally absolutely no difference at all.
I assume what they meant is that there is an overload of the constructor that takes an input of the other class, for example
realnum(ratnum const& other) : number{other.result()} {}
And vice-versa to construct a ratnum from a realnum, although that could be less trivial as there are irrational numbers, infinitely repeating numbers, etc.
You could use this version of the constructor to do something like
ratnum a{2, 4};
realnum b{a}; // This used your "conversion" constructor

Assignment operator=

Suppose I have a class called Complex with 2 parameters real and imag. I want to overload the =(assignment) operator so that I could copy the value from the real parameter and assign it to an int.
If my main would look something like;
Complex z(1, 2);
int a = z;
I want a to be equal to 1.
How can I implement this function/method?
Use cast operator:
//Declaraion
class Complex {
operator int();
}
//Definition
Complex::operator int() {
return real_number;
}
Cast operator can implicitly convert a class instance to a certain type that is defined. It is a handy tool, but sometimes can be dangerous and vulnerable, and hard to debug.
When you define the assignment operator you are instructing the compiler on what to do when a value of possibly a different type is assigned to and instance of your class.
In this case instead you want to define what to do when an instance of your class is assigned to a variable of a different non-class type and this is not possible however. In other words it's the receiving instance that defines what to do in case of an assignment and you can customize this only for class types.
Something quite similar is instead to define how an instance of your class should be convertible to another type, e.g. how to convert a complex to an integer, and this conversion will be used also in case of assignment:
struct complex {
double real, imag;
...
operator int () const { return int(real); }
};
It isn't ideal to have code that reads as an assignment of types from different equivalence classes. It is correct that one should use casting instead, but the casting must be made explicit in C++11:
struct Complex {
double r, i;
...
explicit operator int () const { return int(r); }
};
Complex c = { 1.1, 2.2 };
float a = c; // fails with explicit
float a = (float)c; // fails with explicit
int a = c; // fails with explicit
int a = (int)c; // compiles with explicit
Do you really need to define a class for complex? It's part of standard library
Even you can see <complex> (#include <complex>) to find the operators and definitions overloaded
See more here

Deriving from a class with operator overloading

I want to create a collection of classes that behave like math vectors, so that multiplying an object by a scalar multiplies each field by that ammount, etc. The thing is that I want the fields to have actual names, instead of being treated as an index.
My original idea to implement this was creating a base class Rn with the overloads and then create derived classes with the pretty names. Something like this:
#include <iostream>
#include <algorithm>
using namespace std;
template<int N, class X=double>
struct Base{
X xs[N];
Base(){};
Base(X *data){
copy(data, data+N, xs);
}
Base operator*= (double d){
for(int i=0; i<N; i++){
xs[i] *= d;
}
return *this;
}
Base operator* (double d){
Base answer = *this;
answer *= d;
return answer;
}
//also operators for +=, +, multiplication from left, maybe [] too
};
struct Derived : public Base<2>{
Derived(double a, double b){
foo() = a;
bar() = b;
}
double &foo(){ return xs[0]; }
double &bar(){ return xs[1]; }
};
int main()
{
//this is OK:
double data[2] = {0.0, 2.0};
Base<2> b(data);
b = b*17.0;
cout << b.xs[0] << endl;
//I can't do this:
Derived x(0.0, 2.0);
x = x*17.0;
cout << x.foo() << endl;
return 0;
}
I get a compiler error whenever I try to use of of the operators that requires copying.
gcc gave me the following compiler error:
teste.cpp: In function ‘int main()’:
teste.cpp:52: error: no match for ‘operator=’ in ‘x = x.Derived::<anonymous>.Base<N, X>::operator* [with int N = 2, X = double](1.7e+1)’
teste.cpp:31: note: candidates are: Derived& Derived::operator=(const Derived&)
I think the problem is that the overloading functions deal with Base objects that can't be converted to Derived ones, so I can't use them in the derived class. However, I can't come up with a solution. Is there a way around this or should I use a totally different approach?
Bonus question: is there some way that I can use std::valarray to keep from having to type lots and lots of operator overloads?
Your Base operators (* in this case) can accept Derived object, but they return a Base, which can't be used as a right-hand operand in Derived default assignment operator. Easiest way to fix this is just add an assignment operator to Derive that will take a Base:
Derived& operator= (const Base<2>& other)
You will have to add it to any derived class, but the implementation is rather straightforward (you can have a void CopyOtherBase function in Base that will do the copy, and have all operator= call it and return *this).
I'll only address the technical difficulty, not whether this is a good idea or not.
The problem is that the result of operator* of Derived is a Base, and operator= of Derived (which is a default operator=) doesn't know how to "eat" a Base.
A simple solution is to create a constructor of Derived that gets a Base, and does whatever is needed to initialize itself correctly. This would allow an on-the-fly conversion of a Base to a Derived - and would work for all other operators of Derived that expect a Base.
Something along the lines of -
Derived(const Base<2>& B) : Base<2>( B )
{
}
I think you're going to be much better off using an enum or static constants to name your fields
e.g., static const int FIELD_NAME = 0;
Static const int FIELD_NAME2 = 1;
than doing this as different types (templates). Then you can go for std::valarray or boost::ublas::vector/matrix types to leverage existing code & get quality performance vector operations to boot.
Template metaprogramming had an interesting idea on solving just this sort of issue with math vectors, but perhaps doesn't solve your issue of naming the parts.
David Abrahams, Aleksey Gurtovoy: C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond, Addison-Wesley, ISBN 0-321-22725-5
According to MSDN,
All overloaded operators except
assignment (operator=) are inherited
by derived classes.
Could this be your problem?