c++ operator overloading library class - c++

I have a class from Gtk Library that represents a color(GdkColor)....i have written my own interval tree around it...
Basically, it associates different colors to different intervals...
Now,in my test case, once i do a query for interval,
i want to compare the output with the expected value.
typedef struct
{
GdkColor color;
}intervalMetaData;
struct intervalInfo
{
signed int low;
signed int high;
intervalMetaData _data;
};
metaData = _intervalTree.performQuery(BWInterval);
GdkColor red;
//red==metaData.color //throws an error
I cannot overload == for gdkColor since it is from gdk library.
Is there any other way i can get around this??

IF, and only if, you have all the information you need to determine the equality, it is no problem to define the function yourself:
//not sure what GdkColor contains, but if it is large pass by const &
bool operator==(GdkColor a, GdkColor b) {
//check equality here
return result;
}
operator== does not have to be a member function.
If you have no way of comparing two GdkColor instances, you cannot find out if they are equal. Dead simple. If the framework provides no method which allows you to determine equality it probably does so for a good reason. This would usually be something, where neither <,>,<=, >=, !=, == nor anything comparable are provided and access to the members which would define the equality relation is not possible at all. I can't remember wanting to implement an operator==, where this was the case. However, if you have to force the API to its limit to implement an equality-comparison, you should investigate why that is so.
The typical case where you would have no access would be a C library, which uses a typedef to make a struct opaque. However, if it was intended for you to manipulate the contents of the struct or compare them, the framework would provide either something like
xxx getInformationXXX(struct S) or a method int compare(struct S*, struct S*)
I am not familiar with GdkColor, but I assume, there is some publicly available information that allows you to determine if two instances are equal. You should consider putting this function into a namespace, just in case GdkColor ever implements operator== itself to help avoid disambiguation.

operator== should not be the member of the class (and, probably, does not need an access to private/protected part of it), so it can be overloaded.
You can create the derived class and overload just anything you want inside it.
The simplest thing is just a helper function, kind of isEqualTo(), without any overloading at all.

Related

avoiding code duplication in different classes where the function does the same in C++

I'm kinda new to OOP so this question feels a bit weird but I want to know what I should do in this case
Say I have a Tup4 class which just holds 4 doubles, and two classes Point4 and Vec4 that extend Tup4. Now, checking for equality in Tup4 is just comparing whether all 4 doubles in each tuple are (approximately) equal. This holds in both classes extending it. However, it makes no sense to define an equality function in Tup4, because then I would be able to check for equality between a Point and a Vector, which doesn't make much sense. So I can't define a virtual equals method in Tup4, so what can I do? The code is exactly the same in both cases, the only difference is the type of the function. So I want to know if I can avoid having two methods
bool equals(Point4 p);
bool equals(Vec4 v);
Where they both do the same but are defined in different classes
It looks like you already accepted an answer, but here's what I was going to
I propose without going down the template route:
Define an equality method in your Tup4 class, but leave it protected:
class Tup4
{
public:
double a, b, c, d;
protected:
bool EqualityCheck(const Tup4& other) const
{
return (a == other.a && b == other.b && c == other.c && d == other.d);
}
};
Then your Point4 and Vec4 classes can have overloaded equality operators that call the parent's method:
class Point4 : public Tup4
{
public:
bool operator==(const Point4& other) const
{
return EqualityCheck(other);
}
};
You can use templates for this.
It actually is not a good use OOP to shoehorn value-like types such as mathematical vectors and points into an object hierarchy. Object hierarchies mean using "reference semantics"; whereas, vectors, tuples, and points want to be values.
Look at, for example, how the C++ standard library implements complex numbers. It implements them as a class template parametrized on the number type you'd like to use e.g. float, double, etc. and then overloads the arithmetic operators to handle complex<T>.
How you would really implement a vector etc. class is similar.
Tup4 is a concept not a class. Vec4 snd Point4 satisfy that concept.
Most of Vec4 and Point4 are implemented as templates.
In the rare case you need to handle Tup4s in runtime polymophic way, don't use inheritance, use type erasure like std function. But you probably won't.
struct Tup4Data{
double v[4];
};
template<class D>
struct Tup4Impl:Tup4Data{
// common implementation details of Tup4
// D is derived class (Vec4 or Point4)
};
struct Vec4:Tup4Impl<Vec4>{
// extra stuff for Vec4
};
struct Point4:Tup4Impl<Point4>{
// extra stuff for Poimt4
};
Now, code that just wants to work on raw doubles and doesn't care can take Tup4Data. Tup4Impl uses the CRTP if you want to look it up; this provides static polymorphism.
Those that care if it is a vector or a point can take either one.
Those that wants to take both and behave differently can be template code, or type erase.
This last case -- type erase -- is harder, but in exchange you get massive improvements in every other case. And 99% of code bases don't even need to type erase.
I'm not even certain what kind of situation has code that wants to type erase here.
So just don't worry about it. (If you want to learn, look up example std function implementations).
You want the two types Point4 and Vector4 to be incompatible with each other, in the sense that they are different types. Now, as yourself what you need the Tuple4 for. Is it really important that Point4 is a Tuple4? In other words, is the Liskov Substitution Principle important there? My guess is that the answer is that Tuple4 is just a convenient baseclass for code reuse, not for OOP reasons.
If my assumption is correct, using a private baseclass would be a better choice. Since the base is private, it won't allow comparing Vector4 and Point4. For convenient code reuse, you can forward to the baseclass implementations:
class Point4: Tuple4 {
public:
bool operator==(Point4 const& rhs) const {
return static_cast<Tuple4 const&>(*this) == static_cast<Tuple4 const&>(rhs);
}
};
That said, consider using std::array as baseclass instead of writing your own.

Proper design for C++ class wrapping multiple possible types

I am trying to implement a C++ class which will wrap a value (among other things). This value may be one of a number of types (string, memory buffer, number, vector).
The easy way to implement this would be to do something like this
class A {
Type type;
// Only one of these will be valid data; which one will be indicated by `type` (an enum)
std::wstring wData{};
long dwData{};
MemoryBuffer lpData{};
std::vector<std::wstring> vData{};
};
This feels inelegant and like it wastes memory.
I also tried implementing this as a union, but it came with significant development overhead (defining custom destructors/move constructors/copy constructors), and even with all of those, there were still some errors I encountered.
I've also considered making A a base class and making a derived class for each possible value it can hold. This also feels like it isn't a great way to solve the problem.
My last approach would be to make each member an std::optional, but this still adds some overhead.
Which approach would be the best? Or is there another design that works better than any of these?
Use std::variant. It is typesafe, tested and exactly the right thing for a finite number of possible types.
It also gets rid of the type enum.
class A {
std::variant<std::wstring, long, MemoryBuffer, std::vector<std::wstring>> m_data{}; // default initializes the wstring.
public
template<class T>
void set_data(T&& data) {
m_data = std::forward<T>(data);
}
int get_index() { // returns index of type.
m_data.index();
}
long& get_ldata() {
return std::get<long>(m_data); // throws if long is not the active type
}
// and the others, or
template<class T>
T& get_data() { // by type
return std::get<T>(m_data);
}
template<int N>
auto get_data() { // by index
return std::get<N>(m_data);
}
};
// using:
A a;
a.index() == 0; // true
a.set_data(42);
a.index() == 1; // true
auto l = a.get<long>(); // l is now of type long, has value 42
a.get<long>() = 1;
l = a.get<1>();
PS: This example does not even include the coolest (in my opinion) feature of std::variant: std::visit I am not sure what you want to do with your class, so I cannot create a meaningful example. If you let me know, I will think about it.
You basically want QVariant without the rest of Qt, then :)?
As others have mentioned, you could use std::variant and put using MyVariant = std::variant<t1, t2, ...> in some common header, and then use it everywhere it's called for. This isn't as inelegant as you may think - the specific types to be passed around are only provided in one place. It is the only way to do it without building a metatype machinery that can encapsulate operations on any type of an object.
That's where boost::any comes in: it does precisely that. It wraps concepts, and thus supports any object that implements these concepts. What concepts are required depends on you, but in general you'd want to choose enough of them to make the type usable and useful, yet not too many so as to exclude some types prematurely. It's probably the way to go, you'd have: using MyVariant = any<construct, _a>; then (where construct is a contract list, an example of which is as an example in the documentation, and _a is a type placeholder from boost::type_erasure.
The fundamental difference between std::variant and boost::any is that variant is parametrized on concrete types, whereas any is parametrized on contracts that the types are bound to. Then, any will happily store an arbitrary type that fulfills all of those contracts. The "central location" where you define an alias for the variant type will constantly grow with variant, as you need to encapsulate more type. With any, the central location will be mostly static, and would change rarely, since changing the contract requirements is likely to require fixes/adaptations to the carried types as well as points of use.

Lambda vs function for sorting

I have a class
class Point
{
private:
int x; int y;
public:
Point(int a, int b):x(a),y(b){}
Point():Point(0,0){}
}
If I want to sort a vector of Points, shall I use a lambda:
std::sort(xSortedPoints.begin(), xSortedPoints.end(),
[](const cv::Point& p1In, const cv::Point& p2In) -> bool {
return (p1In.x < p2In.x);
});
or using a static function in the class:
std::sort(xSortedPoints.begin(), xSortedPoints.end(), xSorting);
where xSorting is defined and declared in the Point class as
static bool xSorting(const Point& p1In, const Point& p2In)
{
return (p1In.x < p2In.x);
}
Why shall I use lambda, or why not?
EDIT:
Because I need to sort in the two ways (by x and by y) I did not define the < operator.
Based on the comments and answers I need to say that I use this in an application that runs continuously, so the sorting is done a lot of times. So what is better to use in my case: static or lambdas? Lambdas are created every time the std::sort is used? If yes, than I think static is the best choice... No?
Lambdas are there for convenience and slick code.
If you prefer to use a static function you should do this. If you use it once consider a lambda.
To my knowledge there is no performance gain when using lambdas.
So either do a static function, put an in place lambda or define less than operator for the class.
Lambda would make the code more concise especially if it's a one-liner like in your case. On the other hand, I would think the static function approach would be prefered if it needs to or can be used in more than 1 place.
This is kind of opinion based but in short:
If it is short and not used often, use a lambda. Your example is short enough. If the function is long or complicated or used often, give it a name.
In this special case, you could think about overloading operator < for Point if it makes sense. Then, no third argument to sort would be required, but you have make sure that < does what the naive reader would expect.
Btw, you can omit the ->bool, the compiler will deduce it automatically.
I don't know if there is any performance issues here, and the answers you get are going to be of the type "IM(H)O ....", so here are my two cents:
In this case, lambda is good in the sense that it shows the person who is reading the code what you mean by comparing two points. Mathematically, 2D (or any higher dimensions for that matter) points don't form an ordered set, so a < operator will be confusing. Having a static function, friend, ... on the other hand puts the definition of the comparison too far from the usage and, again, might add to confusion as the reader has to scroll to the definition to see what you mean by comparing two points.

Reasonable key types for map used to set properties of related classes?

I'm planning to write a code with classes that have inheritance relationships like the following and have various properties that are associated with material types:
Abstract base class Foo. No properties associated with it.
Foo1GeneralElastic inherits from class Foo and has the properties associated with a possibly anisotropic elastic material.
Foo2GeneralElastic also inherits from class Foo and has the same kinds of material properties as Foo1GeneralElastic, but is otherwise different.
Foo1PiezoElastic inherits from Foo1GeneralElastic and has both piezoelectric properties as well as generic elastic ones.
Foo1IsotropicElastic inherits from Foo1GeneralElastic, but does not share its properties.
I decided that the abstract base class would have one or more methods that take a map of type MyPropMap, defined as:
typedef std::map<PropertyLabel,std::vector<double> > MyPropMap
I have a few different options on what the PropertyLabel type could be, and I'm trying to weigh the pros and cons of each:
Have the PropertyLabel be an enum: This would be lightweight, but it would basically be a bag of labels for all the different properties of every material that I'm considering.
Have the PropertyLabel be just an int: Here, I'd have separate header files for each material type, each of which would contain definition of static integer constants that would be labels for the relevant material properties. For example, MatPropKeyGenElastic.hpp would define the integer constant ELASTICITY_MATRIX, MatPropKeyIsotropicElastic.hpp would define the constants ELASTIC_MODULUS and POISSONS_RATIO, and MatPropKeyPiezoElastic.hpp would #include the file MatPropKeyGenElastic.hpp and additionally define the constant PIEZO_CONST_MATRIX.
The tricky thing would be to make sure that none of the constants that could be used together would have the same values. That could be accomplished by generating the header files with a script that would set the values of these constants to unique values.
Have the PropertyLabel be a std::string From here I could take things a few different ways. I could just have string literals like "ELASTICITY_MATRIX" in the code and rely on these literals never being misspelled---an error that would be caught at run-time rather than compile time. I could define string constants in way analogous to the scheme above for integer constants, and the task of keeping the constants unique would be trivial: just set the value of ELASTICITY_MATRIX to "ELASTICITY_MATRIX", the value of POISSONS_RATIO to "POISSONS_RATIO", etc.
The catch I see with that, aside from the extra overhead, is that I've seen horror stories relating to global static constants of non-PODs, such as those in the comments in the topics non-integral constants and Defining class string constants in C++?. I suppose that I could have the global static constants be const char[] arrays, which are PODs that would be implicitly converted into std::strings when used as map keys (and, no, I am not planning on letting the map key itself be const char*). I could also define the string literals with the preprocessor, but then I couldn't keep them within a namespace.
Would you recommend any of the above approaches? Are there hidden traps in them that I hadn't noticed? Are there still other approaches that you would recommend?
I don't recommend to use strings. It's too expensive for such simple task. I vote for enum.
But if it looks too ugly to you to keep all label constants in a single place, you could elaborate more complex approach - use a composite key like pair of two numbers - (class ID, property ID).
Both could be defined as enums, maybe nested. Moreover, class ID could be generated automatically - e.g. using reinterpret_cast on std::type_info pointer or just using std::type_info pointer or std::type_index if supported. Illustrating idea with code:
// PropertyLabel type, could be used as associative container key
struct PropertyLabel: std::pair<const std::type_info*, int>
{
// Template ctor allows implicit conversion from enums
// (actually not only from enums but from any int-compatible types)
// Uncomment explicit keyword if implicit conversions scares you and use
// explicit conversion syntax - PropertyLabel(smth).
template <typename T> /*explicit*/ PropertyLabel(T label):
std::pair<const std::type_info*, int>(&typeid(T), label)
{
}
};
// First property holder
class PropertyUser1
{
public:
enum Labels
{
eProperty1,
eProperty2,
eProperty3,
};
};
// Second property holder
class PropertyUser2
{
public:
enum Labels
{
eProperty1,// Due to class scope you could use same names for different properties
eProperty2,
eProperty3,
};
};
// Usage. A bit dangerous due to implicit conversions, but intuitive and handy:
MyPropMap properties;
properties[PropertyUser1::eProperty1].push_back(42.0);
properties[PropertyUser2::eProperty1].push_back(42.42);
// Will be with explicit ctor:
// properties[PropertyLabel(PropertyUser1::eProperty1)].push_back(42.0);
// properties[PropertyLabel(PropertyUser2::eProperty1)].push_back(42.42);
Looks like it could be improved with more type safety eliminating possibility of using non-enum types like int, e.g. disabling calls like PropertyLabel(42). But this is just to illustrate idea.
I just realized a relatively simple solution that would give me pretty much what I want without too much fuss. For any particular instance of the MyPropMap type, I'm dealing with the properties of one particular kind of material: isotropic elastic, piezoelectric, anisotropic elastic, and so on. Given this, I can wrap the enums corresponding to each material type in its own namespace and put them in the appropriate header file, so for example,
// MatPropKey/IsotropicElastic.hpp:
namespace IsotropicElastic {
enum { ELASTIC_MODULUS, POISSONS_RATIO };
}
// MatPropKey/GenElastic.hpp
namespace GenElastic {
enum { ELASTICITY_MATRIX }
}
// MatPropKey/PiezoElastic.hpp
namespace PiezoElastic {
enum { PIEZO_CONST_MATRIX, ELASTICITY_MATRIX }
}
There is some redundancy here, but I can live with that. So long as I stick to the above convention, then within each namespace, the enum values are unique, and so long as I only use the enum values within a particular namespace for each instance of MyPropMap---which I want to do anyway---I'm fine. (Realistically, I'd also want to wrap each of these namespaces within a common MPKey namespace.) Of course, this isn't foolproof. A sufficiently creative fool could, for example, decide to #include both GenElastic.hpp and PiezoElastic.hpp and then use GenElastic::ELASTICITY_MATRIX with the PiezoElastic::PIEZO_CONST_MATRIX. Bad things could then happen. Still, the code communicates how the named constants are supposed to be grouped, and avoiding unwanted name clashes is trivial.
Wish I thought of it earlier.
After some thought, I realized a few things:
It's better to wrap the map within a class, so that I have a bit more control over how it is written.
Even the wrapped map is generic and has to be able to accommodate any material parameter type, so there's only so much compile-type safety that I can provide.
Given this, I decided to design a MatProp class roughly as follows:
#include <vector>
#include <map>
class MatProp {
public:
// Skipping the constructor details ...
void setProp_Raw(int propId, double val);
void getProp_Raw(int propId, double & val) const;
void setProp_Raw(int propId, const std::vector<double> & vals);
void getProp_Raw(int propId, std::vector<double> & vals) const;
// More overloaded set/get funcs for complex scalars and vectors ...
private:
// The typedef allows me to write MatPropMap_::iterator, etc. in the
// implementation of the member functions, which is handy if, say,
// I want to swap the std::map for an unordered_map later on.
typedef std::map<PropertyLabel,std::vector<double> > MatPropMap_;
MatPropMap_ matPropMap_;
};
The set/get functions are suffixed with _Raw because it's easy to put in a wrong combination of property ID and value. I could pass in information to the constructor of MatProp so that the inputs to these functions could be validated at run time, but setting that up could get clunky and make the class harder to use. To add some extra safety, I can do this, for example:
void setIsotropicLinearElasticParameter(MatProps mProp,
ElasPropEnum propId, // ELASTIC_MODULUS and POISSONS_RATIO are the
// *only* valid values of this parameter.
double val) {
mProp.setParam_Raw(propId, val);
}
The function is simple, but I'm declaring clearly that (1) only two keys are allowed and (2) they really are supposed to be of type double. The interface isn't totally foolproof, but it's fairly easy to use correctly and takes some effort to use wrong. FWIW, a similar thing was done here: http://blog.knatten.org/2010/04/23/make-apis-hard-to-use-incorrectly/.

Polymorphic operator on a list of boost::any?

Suppose I have a list of type list<boost::any> that has some type in it that is unknown. Now suppose I want to apply some operation to the elements in the list that is polymorphic. In this case, consider the + operator. Suppose that I know that the list will always contain a homogenous set of objects that support operator+, and I want to get the result of applying operator+ (the "sum" in one sense) between each element of the list into a new boost::any. Something like this:
boost::any sum(list<boost::any> lst) {
// return lst[0]+lst[1]+lst[2] etc
}
Without enumerating all possible types that could support operator+, is there a way to do this? I'm extremely open to crazy ideas.
(I really do have an ok reason for doing this... I'm implementing an interpreter)
You could use boost::variant instead if you know the range of possible types in the list.
I don't see how you can do this without a mesh of operator+ functions to handle every possible combination of contained types, or regular runtime polymorphism.
What is the concrete type you wish to see in the final boost::any output, I wonder?
btw if you are implementing an interpreter, check out Boost.Spirit which might illuminate your design problem here.
C++ matches functions (and operators are merely fancy functions that have an additional infix syntax) by their types, not by their names, at compile-time. (Rather than checking at run-time whether the objects involved support the requested operation.)
The only exception to that I can think of is virtual functions. If the types were polymorphic, you could use any of the workarounds for missing multi-methods (double dispatch). But since they can be anything, I don't think you can do this.
If you have a limited set of types, template-meta programming might help the generate functions implementing addition. But if the number of types involved were limited, you'd probably use boost::variant.
(IME saying this means that, in very short time, someone comes along and proves me wrong.)
No. Not with boost::any nor with boost::variant (doesn't qualify your, "Without enumerating all possible types that could support operator+," requirement).
What you need to do is make your own. The concept behind boost::any is quite simple. If you look at the documentation they have a link to an article explaining the technique (it's basically the handle/body idiom with polymorphism). All you need to do is decide what interface your various objects must have and write the 'any' interface and it's impl accordingly. Something resembling something like so:
struct my_any
{
template < typename T >
my_any(T const& t) : pimpl(new impl<T>(t)) {}
...
some_type get_some_type() const;
...
private:
struct impl_base
{
....
virtual some_type get_some_type() const = 0;
};
template < typename T >
struct impl : impl_base
{
some_type get_some_type() const { return t.get_some_type(); }
impl(T const& t_var) : t(t_var) {}
....
};
boost::scoped_ptr<impl_base> pimpl;
};
some_type operator+ (my_any const& a, my_any const& b)
{
return a.get_some_type() + b.get_some_type();
}
It's hard to imagine what operator+ would do on generic types so I made something up that makes a small amount of sense to me. You'll of course need to change to your needs.