Is it possible to inherit identically named operator which only differ in return type, from two different abstract classes.
If so, them:
what is the syntax for implementing operators
what is the syntax for using/resolving operators
what is the overhead in general case, same as for any other virtual function?
if you can provide me with a reference or sample code that would be helpful
thanks
12struct abstract_matrix {
13 virtual double& operator()(int i, int j);
14};
15
16 struct abstract_block_matrix {
17 virtual double* operator()(int i, int j);
18 };
19
20struct block_matrix : abstract_matrix, abstract_block_matrix {
21
22};
block matrix needs to provide implementations for both operators, so that it is either a matrix or a block matrix, depending on the context. I do not know how to provide implementation specific to block_matrix class.
right now, it is done by passing object wrapped type as the last argument, but that does not seem very clean. I would like to retain pure matrix notation.
The return type of a function is not part of it's signature, so you can't have two operator+(i,j)'s in block_matrix - that would be an ambiguous call. So multiple inheritance is sort of a red herring here on this point. You just can't do that.
What are you really trying to do, and why?
In any event, for your other question: virtual operators are exactly like virtual functions in terms of performance and the way they operate. There are just slight semantic differences in how you use them - but under the hood they're just functions like any other.
You can't overload on the return type. When a function or an operator is invoked the compiler has to know which one to call. It will not infer that based on what the function(operator) call assigned to.
Looks like your are looking to implement some matrix math. Perhaps if you download DirectX SDK or OpenGL and have a look how they do it, you might get some ideas on how to do it properly.
I got it work, but it's wonky. I do love templates.
template<class T>
class Base1
{
};
template<class T>
class Base2
{
};
class Derived;
template<>
class Base1<Derived>
{
public:
double foo(){return 0.1;}
};
template<>
class Base2<Derived>
{
public:
int foo(){return 1;}
};
class Derived
: public Base1<Derived>
, public Base2<Derived>
{
public:
using Base1<Derived>::foo;
};
int main()
{
double sum = 0;
Derived d;
sum += d.foo(); //+ .1
Base1<Derived> * pI = &d;
sum += pI->foo(); //+ .1
Base2<Derived> * pF = &d;
sum += pF->foo(); //+ 1
return (sum*10);
}
I couldn't get it to work without templates, although it seems like it should be able to. I'm not sure if you can get away with just doing templated member functions in the same manner, but my gut says "no".
In terms of code organization, I would then define the Base# stuff right after the definition or declaration of Derived, since that's really what it's for. Keep in mind you can then use typename Base1<Derived> something to make things prettier.
Edit:
Oh, right! It doesn't allow you to do the "using" trick or have different return types, but it's otherwise simpler:
class Derived
: public Base1
, public Base2
{
double Base1::foo(){...}
double Base2::foo(){...}
}
There may be a terrible, horrible, awesome way to combine these two approaches, but I don't think it'll actually help out when using the code. I may get back to you on that.
Related
Suppose I have some C++ code that looks like this:
class Base {
virtual void dummy() = 0;
// this is to generate a vtable, but note there is no virtual f()
};
class A : public Base {
public:
void f() { /* ... */ };
void dummy() {};
}
class B : public Base {
public:
void f() { /* different implementation from A */ };
void dummy() {};
}
template<class T1, class T2, class T3>
void doStuff(T1 &x, T2 &y, T3 &z) {
for (i=1; i<100000; ++i) {
x.f();
y.f();
z.f();
}
}
The intention here is to avoid virtual function calls to f() during that inner loop, in order to allow compiler optimisations. (This is obviously a simplified version of my actual code. For details of my use case, see this more specific question).
This works fine if the types of doStuff's arguments are known at run-time, but if they're not then it fails:
int main() {
Base *x = new A();
Base *y = new B();
Base *z = new A();
doStuff(*x, *y, *z);
// oops - this instantiates to doStuff(Base &, Base &, Base &)
// and there's no Base::f().
}
to get around this (as suggested by this answer) it seems I have to construct a static dispatch function explicitly:
void doStuff(Base &x, Base &y, Base &z) {
A *a_x = dynamic_cast<A*>(&x);
B *b_x = dynamic_cast<B*>(&x);
A *a_y = dynamic_cast<A*>(&y);
B *b_y = dynamic_cast<B*>(&y);
A *a_z = dynamic_cast<A*>(&z);
B *b_z = dynamic_cast<B*>(&z);
if (a_x && a_y && a_z) {
doStuff(*a_x, &a_y, &a_z);
} else if (a_x && a_y && b_z) {
doStuff(*a_x, &a_y, &b_z);
}
// ... and so on for all eight combinations of A and B.
}
But that's some pretty annoyingly repetitive code, and if I have several functions along the lines of doStuff it will quickly get unmanageable, especially if any of them have four or more arguments.
So my question is, is there any way to avoid this repetitive code? It seems like some further clever use of templates should be able to eliminate it, but I can't quite see how to do it.
The title of your question: "static dispatch" - unfortunately your problem requires finding out the type at runtime... You want to identify the actual type from some base class pointers. This will work only at runtime.
Using dynamic_cast is a hack, the usage of dynamic_cast along usually means bad OO design. BTW, my bet would be that using dynamic_cast (dynamic_cast can be pretty slow!) and then a static function call is slower than simply making f() virtual and putting it to your base class and calling it that way.
Of course your case is a bit more special, you want to perform something else for all 8 cases but this is a piece of dirt work you won't be able to solve elegantly with brief code in C++ in my opinion. It is possible to forge a solution that is less error prone/easy to extend or one that is better in performance but none of them will be brief and/or elegant. Your current doStuff() implementation is rather a less error prone "bulletproof" solution, another one ugly solution has just came to my mind that would have good performance even for a lot of derived classes and class combinations (own type enum with own gettype + switch) but that is ugly as hell.
Summing it up: This problem has no nice solution in C++. You have to rethink your design or you have to live with ugly code when it comes to problems that can not be solved elegantly in C++: for example in case of serialization you often find ugly code like this...
This is a classical multiple-dispatch problem. It's very well developed in the literature. One of the solutions is the Visitor pattern (you need to apply it twice as you have 3 arguments to dispatch on). Another one is a map<tuple<type_info, type_info, type_info>, StuffDoer> (the latter class should have a virtual doStuff method and do a dynamic_cast to all arguments inside).
I have some classes:
class Base
{
public:
virtual void Something() = 0;
}
class A : public Base
{
public:
virtual void Something() { /*...*/ }
void SpecialActionForA();
}
class B : public Base
{
public:
virtual void Something() { /*...*/ }
void SpecialActionForB();
}
and an array:
Base* MyMembers[2];
MyMembers[0] = new A;
MyMembers[1] = new B;
and I want to do:
A* pointer_to_a = Get(0);
B* pointer_to_b = Get(1);
Is there any good way to implement this Get() function?
My solution is:
template <typename T>
T* Get(int index)
{
return dynamic_cast<T*>(MyMembers[index]);
}
But first thing is that I have to write
A* pointer_to_a = Get<A>(0)
Which requires an additional <A>;
Second thing is that if somehow the new is screwed up like:
MyMembers[0] = new B;
Then the Get() is failed.
What I want is something like an automatic mechanism which can maps index 0 to A.
Extra details:
Actually I have 80 different classes derived from Base (They are my User Interfaces),
and my need is to get the real classes (the real UIs) to do things.
The functions I need to use are the above SpecialActionForA()...etc.
The Something() is also used, but is in the initialization stage of these UIs, or something managed by the UI manager system.
You cannot do unknown* Get(int) in principle as it will require two or more functions having the same name but differing only by return value. C++ explicitly prohibits this.
The closest function that you can get is this:
template <typename T> T* Get() {
static T* instance = new T;
return instance;
}
so you will be able to use it as:
A *a = Get<A>();
B *b = Get<B>();
Overloading of function works by looking up the argument list. It is not possible to understand what kind of the value you want by judging only the return type. Thus compiler forces you to give extra detail to instantiate the template. So your options are:
Base *Get(int N) {
return MyMembers[N];
}
or
A *GetA(int N) {
return MyMembers[N];
}
B *GetB(int N) {
return MyMembers[N];
}
or
template <typename T> void Get(int N, T *&item) {
item = (T*)MyMembers[N];
}
A* pointer_to_a;
B* pointer_to_b;
Get(0, pointer_to_a);
Get(1, pointer_to_b);
or your own
template <typename T>
T* Get(int index)
{
return dynamic_cast<T*>(MyMembers[index]);
}
Without knowing your usage scenario, it'll be a bit hard to provide a useful answer, but I actually do believe what you want is type matching. So what you do is that you pass your variables around as Base pointers until I you actually need to know the concrete underlying type, at this point you do a matching on the underlying type of your base pointer. This is works pretty much alike a switch statement mixed with lambdas, I'll try to provide an example.
...
Base* ptr = some_argument;
// Here we need the underlying type, so we'll do a match
Match(ptr)
{
Case(A* a)
{
// this is invoked if ptr happened to hold an A, now do something A specific.
}
Case(B* b)
{
// this is invoked if ptr happened to hold a B, now do something B specific
}
Otherwise()
{
// this is invoked whenever none of the above are
}
}
EndMatch;
...
This is an alternative to the usual solution, which is virtual pointers in the base class, and overriding. Note that type matching is commonly used in functional languages. For C++ there's a cleaver solution to achieving this, by Yuriy Solodkyy one of Bjarne Stroustrup's PhD students.
The short introductury paper can be found here;
https://parasol.tamu.edu/~yuriys/papers/OPM13EA.pdf
For a more information, check out hvis paper, which was presented to the ISO comitee; Open and Efficient Type Switch for C++ by Stroustup, Dos Reis and Solodkyy
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3449.pdf
For the source code behind these papers goto Yuriys homepage at;
https://parasol.tamu.edu/~yuriys/pm/
If the number of classes you've got is truly closed, then consider using closed algebraic data types, as with boost::variant.These are have a few advantages over the unrestricted open algebraic data types, in that the compiler can usually ensure exhaustive matching, and in that the closed nature allows for more optimized pattern matching implementations, though at the cost of flexibility.
Also do note that boost::variant works nicely on C++03!
Do however please consider if you really need pattern matching or polymorphic dispatching. Both approaches are advantages and downsides, the main advance of the pattern matching approach, is that you aren't required to change your classes, and that you avoid polluting your base class with ultra specific virtual methods, which may only be called in a single location.
I have the following design problem and am seeking for the most elegant and even more important most efficient solution as this problem comes from a context where performance is an issue.
Simply spoken I have a class "Function_processor" that does some calculations for real functions (e.g. calculates the roots of a real function) and I have another class "A" that has different such functions and needs to use the Function_processor to perform calculations on them.
The Function_processor should be as generic as possible (e.g. do not provide interfaces for all sorts of different objects), but merely stick to its own task (do calculations for any functions).
#include "function_processor.h"
class A {
double a;
public:
A(double a) : a(a) {}
double function1(double x) {
return a*x;
}
double function2(double x){
return a*x*x;
}
double calculate_sth() {
Function_processor function_processor(3*a+1, 7);
return function_processor.do_sth(&function1);
}
};
class Function_processor {
double p1, p2;
public:
Function_processor(double parameter1, double parameter2);
double do_sth(double (*function)(double));
double do_sth_else(double (*function)(double));
};
Clearly I can not pass the member functions A::function1/2 as in the following example (I know that, but this is roughly what I would consider readable code).
Also I can not make function1/2 static because they use the non-static member a.
I am sure I could use sth like std::bind or templates (even though I have hardly any experience with these things) but then I am mostly concerned about the performance I would get.
What is the best (nice code and fast performance) solution to my problem ?
Thanks for your help !
This is not really the best way to do this, either from a pure OO point of view or a functional or procedural POV. First of all, your class A is really nothing more than a namespace that has to be instantiated. Personally, I'd just put its functions as free floating C-style ones - maybe in a namespace somewhere so that you get some kind of classification.
Here's how you'd do it in pure OO:
class Function
{
virtual double Execute(double value);
};
class Function1 : public Function
{
virtual double Execute(double value) { ... }
};
class FunctionProcessor
{
void Process(Function & f)
{
...
}
}
This way, you could instantiate Function1 and FunctionProcessor and send the Function1 object to the Process method. You could derive anything from Function and pass it to Process.
A similar, but more generic way to do it is to use templates:
template <class T>
class FunctionProcessor
{
void Process()
{
T & function;
...
}
}
You can pass anything at all as T, but in this case, T becomes a compile-time dependency, so you have to pass it in code. No dynamic stuff allowed here!
Here's another templated mechanism, this time using simple functions instead of classes:
template <class T>
void Process(T & function)
{
...
double v1 = function(x1);
double v2 = function(x2);
...
}
You can call this thing like this:
double function1(double val)
{
return blah;
}
struct function2
{
double operator()(double val) { return blah; }
};
// somewhere else
FunctionProcessor(function1);
FunctionProcessor(function2());
You can use this approach with anything that can be called with the right signature; simple functions, static methods in classes, functors (like struct function2 above), std::mem_fun objects, new-fangled c++11 lambdas,... And if you use functors, you can pass them parameters in the constructor, just like any object.
That last is probably what I'd do; it's the fastest, if you know what you're calling at compile time, and the simplest while reading the client code. If it has to be extremely loosely coupled for some reason, I'd go with the first class-based approach. I personally think that circumstance is quite rare, especially as you describe the problem.
If you still want to use your class A, make all the functions static if they don't need member access. Otherwise, look at std::mem_fun. I still discourage this approach.
If I understood correctly, what you're searching for seems to be pointer to member functions:
double do_sth(double (A::*function)(double));
For calling, you would however also need an object of class A. You could also pass that into function_processor in the constructor.
Not sure about the performance of this, though.
So, I have a single templated class, B, which inherits from a non-template class A. Now, this templated version B, has a set of four valid and known template classes, call them B<uint8_t>, B<uint16_t>, B<uint32_t>, B<uint64_t>.
Currently, I am storing these in a map, boost::unordered_map<std::string, A>, and I would like to create some way to cast to the different types. I can easily differentiate based on a A::width() method which returns 8, 16, 32, or 64 respectively.
I have been racking my brain for a good design but I can't figure out a way to get a better solution than having every use casting themselves.
Here is a minimum working case:
class A {
std::size_t width() const = 0;
};
template <typename value> class B : public A {
std::size_t width() const {
return sizeof(value) * 8;
}
};
Within usage:
boost::unordered_map<std::string, A *> _bmap;
template <class T> T cast_A(A * const a) {
switch (a->width()) {
case 8: return dynamic_cast<B<uint8_t> *>(a);
// removed for brevity
}
The problem with this is that it forces the user to check the runtime type of the A class after, aka making the cast method absolutely useless.
I welcome any input. :)
You could use, e.g., a templated get() method which converts to the asked for size via a virtual method going through the largest supported type. If the conversion would loose bits (checked at run-time) you could produce an error.
I think the downcasting is not very good idea in this case. It seems to be a design problem.
However, you could try to implement something like visitor pattern for these classes. It may solve your problem, but I'm not sure, because there are no use examples of B objects.
I have a class:
class A
{
public:
virtual void func() {…}
virtual void func2() {…}
};
And some derived classes from this one, lets say B,C,D... In 95 % of the cases, i want to go through all objects and call func or func2(), so therefore i have them in a vector, like:
std::vector<std::shared_ptr<A> > myVec;
…
for (auto it = myVec.begin(); it != myVec.end(); ++it)
(*it).func();
However, in the rest 5 % of the cases i want to do something different to the classes depending on their subclass. And I mean totally different, like calling functions that takes other parameters or not calling functions at all for some subclasses. I have thought of some options to solve this, none of which I really like:
Use dynamic_cast to analyze subclass. Not good, too slow as I make calls very often and on limited hardware
Use a flag in each subclass, like an enum {IS_SUBCLASS_B, IS_SUBCLASS_C}. Not good as it doesnt feel OO.
Also put the classes in other vectors, each for their specific task. This doesnt feel really OO either, but maybe I'm wrong here. Like:
std::vector<std::shared_ptr<B> > vecForDoingSpecificOperation;
std::vector<std::shared_ptr<C> > vecForDoingAnotherSpecificOperation;
So, can someone suggest a style/pattern that achieves what I want?
Someone intelligent (unfortunately I forgot who) once said about OOP in C++: The only reason for switch-ing over types (which is what all your suggestions propose) is fear of virtual functions. (That's para-paraphrasing.) Add virtual functions to your base class which derived classes can override, and you're set.
Now, I know there are cases where this is hard or unwieldy. For that we have the visitor pattern.
There's cases where one is better, and cases where the other is. Usually, the rule of thumb goes like this:
If you have a rather fixed set of operations, but keep adding types, use virtual functions.
Operations are hard to add to/remove from a big inheritance hierarchy, but new types are easy to add by simply having them override the appropriate virtual functions.
If you have a rather fixed set of types, but keep adding operations, use the visitor pattern.
Adding new types to a large set of visitors is a serious pain in the neck, but adding a new visitor to a fixed set of types is easy.
(If both change, you're doomed either way.)
According to your comments, what you have stumbled upon is known (dubiously) as the Expression Problem, as expressed by Philip Wadler:
The Expression Problem is a new name for an old problem. The goal is to define a datatype by cases, where one can add new cases to the datatype and new functions over the datatype, without recompiling existing code, and while retaining static type safety (e.g., no casts).
That is, extending both "vertically" (adding types to the hierarchy) and "horizontally" (adding functions to be overriden to the base class) is hard on the programmer.
There was a long (as always) discussion about it on Reddit in which I proposed a solution in C++.
It is a bridge between OO (great at adding new types) and generic programming (great at adding new functions). The idea is to have a hierachy of pure interfaces and a set of non-polymorphic types. Free-functions are defined on the concrete types as needed, and the bridge with the pure interfaces is brought by a single template class for each interface (supplemented by a template function for automatic deduction).
I have found a single limitation to date: if a function returns a Base interface, it may have been generated as-is, even though the actual type wrapped supports more operations, now. This is typical of a modular design (the new functions were not available at the call site). I think it illustrates a clean design, however I understand one could want to "recast" it to a more verbose interface. Go can, with language support (basically, runtime introspection of the available methods). I don't want to code this in C++.
As already explained myself on reddit... I'll just reproduce and tweak the code I already submitted there.
So, let's start with 2 types and a single operation.
struct Square { double side; };
double area(Square const s);
struct Circle { double radius; };
double area(Circle const c);
Now, let's make a Shape interface:
class Shape {
public:
virtual ~Shape();
virtual double area() const = 0;
protected:
Shape(Shape const&) {}
Shape& operator=(Shape const&) { return *this; }
};
typedef std::unique_ptr<Shape> ShapePtr;
template <typename T>
class ShapeT: public Shape {
public:
explicit ShapeT(T const t): _shape(t) {}
virtual double area() const { return area(_shape); }
private:
T _shape;
};
template <typename T>
ShapePtr newShape(T t) { return ShapePtr(new ShapeT<T>(t)); }
Okay, C++ is verbose. Let's check the use immediately:
double totalArea(std::vector<ShapePtr> const& shapes) {
double total = 0.0;
for (ShapePtr const& s: shapes) { total += s->area(); }
return total;
}
int main() {
std::vector<ShapePtr> shapes{ new_shape<Square>({5.0}), new_shape<Circle>({3.0}) };
std::cout << totalArea(shapes) << "\n";
}
So, first exercise, let's add a shape (yep, it's all):
struct Rectangle { double length, height; };
double area(Rectangle const r);
Okay, so far so good, let's add a new function. We have two options.
The first is to modify Shape if it is in our power. This is source compatible, but not binary compatible.
// 1. We need to extend Shape:
virtual double perimeter() const = 0
// 2. And its adapter: ShapeT
virtual double perimeter() const { return perimeter(_shape); }
// 3. And provide the method for each Shape (obviously)
double perimeter(Square const s);
double perimeter(Circle const c);
double perimeter(Rectangle const r);
It may seem that we fall into the Expression Problem here, but we don't. We needed to add the perimeter for each (already known) class because there is no way to automatically infer it; however it did not require editing each class either!
Therefore, the combination of External Interface and free functions let us neatly (well, it is C++...) sidestep the issue.
sodraz noticed in comments that the addition of a function touched the original interface which may need to be frozen (provided by a 3rd party, or for binary compatibility issues).
The second options therefore is not intrusive, at the cost of being slightly more verbose:
class ExtendedShape: public Shape {
public:
virtual double perimeter() const = 0;
protected:
ExtendedShape(ExtendedShape const&) {}
ExtendedShape& operator=(ExtendedShape const&) { return *this; }
};
typedef std::unique_ptr<ExtendedShape> ExtendedShapePtr;
template <typename T>
class ExtendedShapeT: public ExtendedShape {
public:
virtual double area() const { return area(_data); }
virtual double perimeter() const { return perimeter(_data); }
private:
T _data;
};
template <typename T>
ExtendedShapePtr newExtendedShape(T t) { return ExtendedShapePtr(new ExtendedShapeT<T>(t)); }
And then, define the perimeter function for all those Shape we would like to use with the ExtendedShape.
The old code, compiled to work against Shape, still works. It does not need the new function anyway.
The new code can make use of the new functionality, and still interface painlessly with the old code. (*)
There is only one slight issue, if the old code return a ShapePtr, we do not know whether the shape actually has a perimeter function (note: if the pointer is generated internally, it has not been generated with the newExtendedShape mechanism). This is the limitation of the design mentioned at the beginning. Oops :)
(*) Note: painlessly implies that you know who the owner is. A std::unique_ptr<Derived>& and a std::unique_ptr<Base>& are not compatible, however a std::unique_ptr<Base> can be build from a std::unique_ptr<Derived> and a Base* from a Derived* so make sure your functions are clean ownership-wise and you're golden.