How to achieve constexpr pseudopolymorphism? - c++

In a ray tracing project that I'm trying to make compile-time (constexpr) for fun and challenge, I've run into a bit of an issue: I have an object (intersection) that needs to refer to one of a group of other objects (shapes).
Now, my understanding is that you cannot use polymorphism / virtual methods with constexpr because of the vtable lookups, so as far as I know, I cannot have a superclass, Shape, from which the other classes derive. Thus, I need to make Intersection a template class that holds one of its shapes.
Unfortunately, I need to store these Intersection classes in an array or some other container, and I want to be able to call a common function on them and their shape, i.e. where the pseudopolymorphism comes in.
I implemented something that solves the problem, where I take an std::array of std::variant and whenever I add to the array, if the type isn't represented by anything in the std::variant, then I expand it. I can also achieve pseudopolymorphism by using std::visit, invoking a commonly named function on each element to result in an std::array of final elements.
My implementation is here, in this gist. I thought it would be too long to post:
https://gist.github.com/sraaphorst/28998c109f94a78616e7dd488c1491d1
Now, I've been known to solve problems with much more difficulty than is necessary, so I was wondering if any of you know of a simpler way to achieve this?

Related

Abstract class, abstract method parameters and inheritance

I joined a research project in which the OOQP library is used. It uses an abstract class OoqpVector (inherited by several subclasses) and a number of methods, such as:
virtual double dotProductWith(OoqpVector& v) = 0
This method is implemented by subclasses SimpleVector and DistributedVector. Because of genericity, OoqpVector::dotProductWith allows all possible combinations:
SimpleVector.dotProductWith(SimpleVector)
DistributedVector.dotProductWith(DistributedVector)
SimpleVector.dotProductWith(DistributedVector)
DistributedVector.dotProductWith(SimpleVector)
However in practice, the method is called on vectors of the same type only (combinations 1 and 2). Therefore, the authors implemented SimpleVector::dotProductWith(OoqpVector&) and DistributedVector::dotProductWith(OoqpVector&) by dynamically casting the parameter to the current type.
Although this works, I find it a bit ugly and wonder if we can implement the same behavior without casts.
An option would be to get rid of OoqpVector::dotProductWith, declare the specialized methods SimpleVector::dotProductWith(SimpleVector&) and DistributedVector::dotProductWith(DistributedVector&), and force the calling methods to impose the two vector types to be equal. However, our code uses a bunch of OoqpVectors everywhere and is relatively generic, so this might be difficult to achieve.
Do you see a way to fix that?
Best,
Charlie

Store any value and a value of a specific range of classes

I have a class that looks something like this:
class container{
private:
std::vector<physical_component> physical;
std::vector<storage_component> storage;
--some other stuff not relevant--
public:
--constructors, getters setters, methods to add to the vectors etc--
}
Now I am struggeling with making the physical_component and storage_component classes since I dont know a proper datatype to handle this sort of thing.
Physical_component should be able to:
Store a set amount of types, and fully retaining a type (something I can cast to is good enough)
Should store the objects in a way that makes them individual from the ones passed (and therefore secure from changes to the orignial class)
I remember something like that excisting in c alongside enum but I dont know the name. Also c++ probably has a better way for that.
Storage_component is supposed to:
Store any type
(optional) remember the original type
I have no idea how to achieve this properly. I saw std::any but it seems to be rather new therefore I dont know if its a good way to go about this. Also I cant make storage_component a template because I cant store it in a vector then
What is the (proper) way to implement these classes?
Store a set amount of types, and fully retaining a type
You probably want std::variant<Ts...> (or boost::variant<Ts...>). It stores one of Ts... at a particular point in time.
Store any type
If all the types share the same interface, use a traditional virtual + std::unique_ptr polymorphism approach. Otherwise std::any is the right choice here.

C++ Template Classes, Inheritance and Writing Generic Code for Graph Drawing

Background Info
I am writing a graph-drawing program. I have encountered a problem with templates and inheritance, and I do not know how to proceed. I do not know how I should design my code to enable me to do what I am trying to do. (Explanation below.)
Target
I have a template class, which represents "data". It looks something like the following:
template<typename T>
class GraphData
{
std::vector<T> data_x;
std::vector<T> data_y; // x and y should be held in separate vectors
}
This class is part of an inheritance hierarchy involving several classes.
The hierarchy looks something like this... (Sorry this is from my notes, awful diagram.)
Explanation
There is a base class. No real reason to have it right now, but I anticipate using it later.
Base_Legend adds functionality for legend drawing. New members added include a std::string, and Get/Set functions.
Base_Drawable adds a pure abstract = 0 member. void Draw(...). This is to force overloading in all inherited objects which are drawable.
GraphData_Generic adds functionality for adding/removing data points to a set of vectors. These are pure abstract methods, and must be overridden by any data classes which inherit.
GraphData and HistogramData are 2 data types which have implementations of the functions from GraphData_Generic. (No implementation of Draw().)
GraphData_GenericDrawable doesn't do anything. It is to be used as a base class pointer, so that a vector of these objects can be used as data (add/remove data points) and can be draw (using void Draw()). This class also can be used to call the Get()/Set() methods for the std::string to be used in the legend.
Finally, at the bottom are GraphData_Drawable and HistogramData_Drawable which overload the void Draw() function. This code specifies exactly how the data should be drawn, depending on whether we have a Histogram or general set of data points.
Problem
Currently, I am using template types. The type of data for the datapoints / histogram bin values is specified by using a template.
For example, one can have a HistogramData<double, HistogramData_Drawable<double>, HistogramData_Drawable<int>, etc... Similarly, one can have GraphData<double>, GraphData<float>, GraphData_Drawable`, etc...
So hopefully it should be fairly obvious what's going on here without me uploading my ~ 10000 lines of code...
Right, so, in addition I have some class Graph, which contains a std::vector<GraphData_Generic_Drawable*>, hence the use of the base class pointer, as suggested above.
BUT! One has to decide what type of data should be used as the underlying type. I MUST choose either std::vector<GraphData_Generic_Drawable<double>*> or std::vector<GraphData_Generic_Drawable<float>*>.
This isn't useful, for obvious reasons! (I could choose double and force the user to convert all values manually, but that's just an easy way out which creates more work later on.)
A (very) ugly solution would be to have a std::vector<> for each possible type... int long unsigned long long double float unsigned char... etc...
Obviously this is going to be hideous and essentially repeat loads of code..
So, I intend to implement an AddData method which adds data to that vector, and I also currently have the following method:
// In class Graph
void DrawAll()
{
for(std::vector<GraphData_Drawable*>::iterator it = m_data.begin(); it != m_data.end(); ++ it)
(*iterator)->Draw(arguments);
} // Draw function takes arguments including a canvas to draw to, but this isn't directly relevant to the question
Which iterates over the vector and calls Draw for each set of data in there.
How to fix it?
My current thoughts are something along the lines of; I need to implement some sort of interface for an underlying data class, which retrieves values independent of the underlying type. But this is only a very vague initial idea and I'm not really sure how I would go about implementing this, hence the question... I'm not sure this is even what I should be doing...
If this isn't clear ask me a question and I'll update this with more details.

List design (Object oriented) suggestion needed

I'm trying to implement a generic class for lists for an embedded device using C++. Such a class will provide methods to update the list, sort the list, filter the list based on some user specified criteria, group the list based on some user specified criteria etc. But there are quite a few varieties of lists I want this generic class to support and each of these varieties can have different display aspects. Example: One variety of list can have strings and floating point numbers in each of its elements. Other variety could have a bitmap, string and special character in each of it's elements. etc.
I wrote down a class with the methods of interest (sort, group, etc). This class has an object of another class (say DisplayAspect) as its member. But the number of member variables and the type of each member variable of class DisplayAspect is unknown. What would be a better way to implement this?
Why not use the std::list, C++ provides that and it provides all the functionality you mentioned(It is templated class, So it supports all data types you can think of).
Also, there is no point reinventing the wheel as the code you write will almost will never be as efficient as std::list.
In case you still want to reinvent this wheel, You should write a template list class.
First, you should probably use std::list as your list, as others have stated. It seems to me that you are having problems more with what to put in the list, however, so I'm focusing on that part of the question.
Since you want to also store multiple bits of information in each element of the list, you will need to create multiple classes, one to store each combination. You don't describe why you are storing mutiple bits of information, but you'd want to use a logical name for each class. So if, for example, you were storing a name and a price (string and a double), you could give the class some name like Product.
You mention creating a class called DisplayAspect.
If this is because you want to have one piece of code print all of these lists, then you should use inheritance and polymorphism to accomplish this goal. One way to accomplish that is to make your DisplayAspect class an abstract class with the needed functions (printItem() for example) pure virtual and have each of the classes you created for the combinations of data be subclasses of this DisplayAspect class.
If, on the other hand, you created the DisplayAspect class so that you could reuse your list code, you should look into template classes. std::list is an example of a template class and it will hold any type you'd like to put into it and in that case, you could drop your DisplayAspect class.
Others (e.g., #Als) have already given the obvious, direct, answer to the question you asked. If you really want a linked list, they're undoubtedly correct: std::list is the obvious first choice.
I, however, am going to suggest that you probably don't want a linked list at all. A linked list is only rarely a useful data structure. Given what you've said you want (sorting, grouping), and especially your target (embedded system, so you probably don't have a lot of memory to waste) a linked list probably isn't a very good choice for what you're trying to do. At least right off, it sounds like something closer to an array probably makes a lot more sense.
If you end up (mistakenly) deciding that a linked list really is the right choice, there's a fair chance you only need a singly linked list though. For that, you might want to look at Boost Slist. While it's a little extra work to use (it's intrusive), this will generally have lower overhead, so it's at least not quite a poor of a choice as many generic linked lists.

What are some 'good use' examples of dynamic casting?

We often hear/read that one should avoid dynamic casting. I was wondering what would be 'good use' examples of it, according to you?
Edit:
Yes, I'm aware of that other thread: it is indeed when reading one of the first answers there that I asked my question!
This recent thread gives an example of where it comes in handy. There is a base Shape class and classes Circle and Rectangle derived from it. In testing for equality, it is obvious that a Circle cannot be equal to a Rectangle and it would be a disaster to try to compare them. While iterating through a collection of pointers to Shapes, dynamic_cast does double duty, telling you if the shapes are comparable and giving you the proper objects to do the comparison on.
Vector iterator not dereferencable
Here's something I do often, it's not pretty, but it's simple and useful.
I often work with template containers that implement an interface,
imagine something like
template<class T>
class MyVector : public ContainerInterface
...
Where ContainerInterface has basic useful stuff, but that's all. If I want a specific algorithm on vectors of integers without exposing my template implementation, it is useful to accept the interface objects and dynamic_cast it down to MyVector in the implementation. Example:
// function prototype (public API, in the header file)
void ProcessVector( ContainerInterface& vecIfce );
// function implementation (private, in the .cpp file)
void ProcessVector( ContainerInterface& vecIfce)
{
MyVector<int>& vecInt = dynamic_cast<MyVector<int> >(vecIfce);
// the cast throws bad_cast in case of error but you could use a
// more complex method to choose which low-level implementation
// to use, basically rolling by hand your own polymorphism.
// Process a vector of integers
...
}
I could add a Process() method to the ContainerInterface that would be polymorphically resolved, it would be a nicer OOP method, but I sometimes prefer to do it this way. When you have simple containers, a lot of algorithms and you want to keep your implementation hidden, dynamic_cast offers an easy and ugly solution.
You could also look at double-dispatch techniques.
HTH
My current toy project uses dynamic_cast twice; once to work around the lack of multiple dispatch in C++ (it's a visitor-style system that could use multiple dispatch instead of the dynamic_casts), and once to special-case a specific subtype.
Both of these are acceptable, in my view, though the former at least stems from a language deficit. I think this may be a common situation, in fact; most dynamic_casts (and a great many "design patterns" in general) are workarounds for specific language flaws rather than something that aim for.
It can be used for a bit of run-time type-safety when exposing handles to objects though a C interface. Have all the exposed classes inherit from a common base class. When accepting a handle to a function, first cast to the base class, then dynamic cast to the class you're expecting. If they passed in a non-sensical handle, you'll get an exception when the run-time can't find the rtti. If they passed in a valid handle of the wrong type, you get a NULL pointer and can throw your own exception. If they passed in the correct pointer, you're good to go.
This isn't fool-proof, but it is certainly better at catching mistaken calls to the libraries than a straight reinterpret cast from a handle, and waiting until some data gets mysteriously corrupted when you pass the wrong handle in.
Well it would really be nice with extension methods in C#.
For example let's say I have a list of objects and I want to get a list of all ids from them. I can step through them all and pull them out but I would like to segment out that code for reuse.
so something like
List<myObject> myObjectList = getMyObjects();
List<string> ids = myObjectList.PropertyList("id");
would be cool except on the extension method you won't know the type that is coming in.
So
public static List<string> PropertyList(this object objList, string propName) {
var genList = (objList.GetType())objList;
}
would be awesome.
It is very useful, however, most of the times it is too useful: if for getting the job done the easiest way is to do a dynamic_cast, it's more often than not a symptom of bad OO design, what in turn might lead to trouble in the future in unforeseen ways.