I'm dealing with an ambiguity problem when overloading the bracket operator with operator[](int) and operator[](std::vector<int>), and using an instance of a class B::public A() that has both bool and std::vector<int> cast operators defined (the issue lies in the boolean cast that can be implicitely converted to int and thus creates ambiguity).
Since the bool cast operator is inherited from A(), is there a way to define it as private within the definition of B()?
CONTEXT:
I'm overloading a storage container class (a simple wrapper around std::vector) and B is a "comparer" class that compares containers value-by-value, and can be cast to a simple bool value for bulk comparison, or std::vector<int> with index positions for true values. This allows me to both perform simple bulk comparisons e.g. if(mat1=mat2) {}as well as apply index masks to my containers e.g. mat1[mat1==14] = // ....
Related
when I go through tutorial here UE4 Basics
I noticed that in CollidingPawn.cpp
A if statement is conditioned on a object if (OurMovementComponent && ...){...}
Which is declared and defined as
class UCollidingPawnMovementComponent* OurMovementComponent;
//...
class HOWTO_COMPONENTS_API UCollidingPawnMovementComponent : public UPawnMovementComponent
{/* ... */};
I think the class have a overloaded () operator, then I trace way back to all its parents, but I could not find one, so I wonder what does the if statement check here, and how it's defined.
OurMovementComponent is defined as a pointer. All pointers can be tested in conditionals, regardless of whether their pointee type has an overloaded operator bool or not.
There is no difference between fundamental types and class types when it comes to pointers to them.
The if statement is checking that the pointer is not null, likely before accessing the object it's supposed to point at, so as to avoid undefined behavior.
I came here to ask something I can't figure out on my own. I've been coding a little class that stores an array of 32 bits and can perform simple mathematic operations like +, -, / and *.
Suppose I have a class like:
class Binary_Class
{
char bin[32]; // 32 bits array to hold an unsigned binary number
void set_dec(int value){}; // setting the bin[32] value based on input value
// I have operator + and = to perform on objects of this class.
Binary_Class& operator= (const Binary_Class&);
const Binary_Class operator+ (const Binary_Class&);
}
Until now, no problem comes up if i declare 3 objects a,b,c of class Binary_Class, then set_dec to a and b, the statement c=a+b can be used (?)
However, I want to extend the class binary by using a new class
class Binary_Class_Extended: public Binary_Class
{
// weird functions
}
If I declare 3 objects a, b, c of class Binary_Class_Extended, am I still able to use c=a+b as the same before that?
In Netbean it says there's no operator= that match my c=a+b if all are of Binary_Class_Extended,
but if I declare c as Binary_Class that statement works. That means a+b returns a const Binary_Class as if the operator+ doesn't get carried to the new class.
Am I missing something or this is the way it is?
Of course, I can post the whole code because it's just an assignment but I think these infos are enough for now.
Update
class Binary_Class
{
char bin[32]; // 32 bits array to hold an unsigned binary number
void set_dec(int value){}; // setting the bin[32] value based on input value
//i have operator + and = to perform on objects of this class.
Binary_Class& operator= (const Binary_Class&);
const Binary_Class operator+ (const Binary_Class&) const;
}
class Binary_Class_Extended: public Binary_Class
{
// weird functions
}
When I try to have all objects of Binary_Class_Extended this error show up:
main.cpp:285: error: no match for 'operator=' in 'sd = ((Binary_Class*)(&sa))->Binary_Class::operator+(((const Binary_Class&)((const Binary_Class*)((Binary_Class*)(&sb)))))'
Binary_ET_Class sa,sb,sc;
sc=sa+sb //initialized sa and sb to non-null value;
The full source code I've been working on: https://pastebin.com/eiVz0f5p
Inherited functions retain their finger prints, so if the Binary_Class operator+ was inherited, it's return value would be ... ?
In general, inheritance and assignment ("value semantics") don't mix easily in C++. In your second case, the "a+b" would return an instance of the baseclass, unless you define a separator operator+ for the derived class. The result is then only assigned to the base-class part of "c", which is triggering the error. This is also sometimes call slicing/truncation. Note that the choice of the operator is at compile time, no virtual functions are called, so the static type has to match.
Don't mix value types and polymorphic types. If you really need to and you have a fixed and known hierarchy, you can use the "Handle-Body Idiom" to preserve derived information when assigning to the baseclass. This is not a beginner topic though.
I have the following class representing numerical arrays
class Array {
protected :
double *data; // this will hold the data of the array
int n; // number of elements in the array
public :
virtual Array operator+ ( double value ) const {
// return a new array with the argument added to each element
}
// other declarations follow here...
};
and another class inheriting from the previous one and adding a boolean mask for each element
class MaskedArray : public Array {
private :
bool *mask; // this holds the boolean mask of the array
public :
MaskedArray operator+ ( double value ) const {
// return a new MaskedArray with the argument added to each element
}
// other declarations follow here...
}
When I try to compile I get the error "invalid covariant return type", which is normal since the two overloaded operators in both classes have the same signature.
I was able to circumvent this problem by passing the argument of the overloaded operator of the inherited class by reference rather than by value, as this changes the signature of the function, while keeping the same interface for both classes. But I feel this is not very clean, and what if I wanted to inherit from MaskedArray ? I would face the same problem.
I want to be able to write stuff like this in my client code
Array array;
// populate array here
Array array2 = array + 1.0;
MaskedArray maskedArray;
// populate maskedArray here
MaskedArray maskedArray2 = maskedArray + 1.0
Is there another more elegant way than my 'hack' to achieve this ?
Covariant means that the return type of an overridden virtual function is inherited from the return type of the base class function.
But: Although covariance is generally supported by C++, the standard allows covariance only when returning pointers or references. operator+ returns by value, that's why you get the compiler error. That is not specific to operators but applies to every function.
Removing the virtual keyword will eleminate the compiler error. But if you do so, keep in mind that applying operator+ to an Array reference or pointer, which actually references a MaskedArray returns an Array (and thus does not contain the mask member. If you cast it to a MaskedArray the original mask is lost).
A workaround for your issue could be using containment instead of inheritance:
class MaskedArray {
private :
Array array;
bool *mask; // this holds the boolean mask of the array
public :
MaskedArray operator+ ( double value ) const {
// return a new MaskedArray with the argument added to each element
}
// delegate public functions
}
Ofcourse, now MaskedArray can't use the protected members of Array (in a lot of cases, this is a good thing) and the public interface must be delegated.
First, your reported error about covariant result is not consistent with the presented code.
It only appears for virtual member functions, and in the presented code, as I write this, there is no such.
Do not in the future waste our time again by asking about what's wrong with your real code, and presenting some made up fantasy code.
Anyway, cure: in your real code, just remove the word virtual.
Also, word of advice: use a std::vector to hold the data and take care of allocation, copying and deallocation.
I want to write a C++ class that offers set operations that work on vectors of strings and vectors of my own data type. Are there any easy ways of doing this rather than writing a different function for each data type? So far I have written operations for string vectors. Below shows an example of my set union:
vector<string> SetOperations::set_union(vector<string> set1,
vector<string> set2) {
for(std::vector<int>::size_type i = 0; i < set1.size(); i++) {
set1.push_back(set2.at(i));
}
return set1;
}
So I want the same thing again but where string is say my_data_type which is a struct of various members. Let's say it looks like this:
struct my_data_type {
int label;
vector<string> x;
vector<string> y;
string str;
};
A function for each data type would also not be as simple as my set_union(...) function because surely I would need to test for equality on each member of my_data_type in the case of set intersection?
Also, I'm quite new to C++ so any comments on my existing function would be appreciated too.
Many thanks.
Some of these already exist and are in the algorithm header:
set_union
set_difference
set_intersection
set_symmetric_difference
These all support a comparator function so that you could do it to all your own data types. Or as posted in the other reply make your Containers comply to the STL requirements.
See: http://www.cplusplus.com/reference/algorithm/
There are already such algorithms (union, intersection, sorting, ...): http://www.cplusplus.com/reference/algorithm/
Your elements simply need to meet the requirements for STL container elements (see http://msdn.microsoft.com/fr-fr/library/bb385469.aspx):
All reference types that are inserted
into STL/CLR containers must have, at
a minimum, the following elements:
A public copy constructor.
A public assignment operator.
A public destructor.
Furthermore, associative containers
such as set and map must have a public
comparison operator defined, which is
operator< by default. Some operations
on containers might also require a
public default constructor and a
public equivalence operator to be
defined.
Like reference types, value types and
handles to reference types that are to
be inserted into an associative
container must have a comparison
operator such as operator< defined.
The requirements for a public copy
constructor, public assignment
operator, and a public destructor do
not exist for value types or handles
to reference types.
You can find information about operator overloading (to be implemented in your custom class) on that WikiBook: http://en.wikibooks.org/wiki/C++_Programming/Operators/Operator_Overloading
Let's say I have:
class myClass
std::list<myClass> myList
where myClass does not define the == operator and only consists of public fields.
In both VS2010 and VS2005 the following does not compile:
myClass myClassVal = myList.front();
std::find( myList.begin(), myList.end(), myClassVal )
complaining about lack of == operator.
I naively assumed it would do a value comparison of the myClass object's public members, but I am almost positive this is not correct.
I assume if I define a == operator or perhaps use a functor instead, it will solve the problem.
Alternatively, if my list was holding pointers instead of values, the comparison would work.
Is this right or should I be doing something else?
The compiler does not automatically generate a default operator==(), so if you don't write one yourself, objects of your class can't be compared for equality.
If you want memberwise comparison on the public members you have to implement that yourself as operator==() (or "manually" use a separate function/functor to do the comparison).
Find does require the value to be equality comparable, and the compiler will not define you a default operator==.
Alternatively, you can use find_if and supply a functor predicate.
std::find needs operator==. Even if the members are public, it doesn't necessarily mean that all of them are relevant in defining what equality means for this class.
If you don't want to overload the operator for some reason (e.g there is no one single intuitive meaning of equality for that class, instances could be consider equal in some respect or another), you can code a suitable function object and use std::find_if. For example:
struct same_surname_as
{
Person p;
same_surname_as(const Person& x): p(x) {}
bool operator()(const Person& person) const { return p.surname == person.surname; }
};
list<Person> li;
find(li.begin(), li.end(), same_surname_as(Person("Pu Songling"));