last day (15 days later) » 

16:19
0
Q: Remove duplicated switch statements caused by not knowing type at compile time of opencv matrix?

snbI have a situation that occurs 5 times in my code, and continues to grow. Basically I have the same switch statement structure every time I need to perform an operation that involves my matrix and its type (which is set dynamically at runtime from files and user input). Here is one such example:...

snb
snb
@gnat most definitely not, the fact that it has switch in the name doesn't mean it helps me (the answers are completely irrelevant to my needs) though it would be nice if there was a duplicate. I'm not looking to put a giant class hierarchy to "solve" this that would just make the code not clean. I need away to have the structure of the switch statement, and also input templated functions into ideally like so: foo<T>(type, bar) where bar is templated inside of foo.
Can you template you whole code (or at least everything that's called once you know the type you are using)?
snb
snb
@Caleth No. the type is only known at runtime, and all the functions that are called with these switch statements are called at runtime, the type can only be known at runtime (I mention this previously, because its defined through UI via user manually selecting type or by loading a separate file). For example, there's a UI function to update the internal matrix with the display widget In order to update the matri I need to set values in the opencv matrix. The only way to set values from a opencv matrix is to also know the type along side it, it is a templated function (at<T>)
@gnat I should mention it isn't just the class hierarchy thing, the question regardless is just not useful and the answers don't address any of my concerns.
What I mean is, you could reduce it from 5 places to one place. int main() { auto type = getType(); switch (type) { case CV_8U: new_main<uint_8t>(); ... } };
snb
snb
@Caleth No, there is more than one entry point in the sense you are talking about, this is UI code, type needs to be derived for from separate instances. events fire off and cause different things to need to happen. For example, the user can edit the type, the user can load a matrix, the rows can be edited (and type must be maintained) or cols must be edited. All of those happen independently from one another, and are initiated from the UI when the user so chooses. Thus separate switches need to exist for each.
16:19
@NicolBolas It sounds like there are a bunch of type-erasing containers, which (hopefully) have been filled with homogeneous objects. It may still be possible to write it in terms of non-type erasing containers
snb
snb
@NicolBolas It is an opencv thing, m_matrix is a cv::Mat the type of the values in a matrix is interpreted pretty much, defined by an integral value for type. you can query the type via .type(). qvariant came from retrieving the value from the UI, i've updated the code to reflect this.
@Caleth yes all objects in both the UI table and m_matrix are homogeneous.
@NicolBolas I've added more context, tell me if I need to add more
I'd be tempted to drop cv::Mat for cv::Mat_<T>, then template MatrixBoxWidget<T> etc. At the point where the user wants to change type, create a whole new UI, and convert the members as appropriate. A plus side will be compile time notification if you miss a conversion
snb
snb
@Caleth I'm not sure that would work for my specific case, QT doesn't do Q_Objects and templates IIRC, but I think it may be work while for you to post an answer about that for future reference (it doesn't have to be very specific). I might be able to bypass the Q_OBJECT thing via encapsulating it in another widget which swaps MatrixBoxWidgets<T> and links events to it. It wouldn't be pretty though.
You can have a abstract MatrixBoxWidgetBase with all the signal handling and a MatrixBoxWidget<T> concrete subclass. Or have a templated pimpl for your matrix UI
snb
snb
@Caleth templates = no Q_OBJECT = no signals.
16:19
Yes, that's why I'm suggesting a non templated base, with a templated subclass / pimpl
class MatrixBoxWidget : public QWidget
{
Q_OBJECT;

public signals:
void foo();
slots:
void onBar() = 0;
// ...
private:
std::unique_ptr<class MatrixBoxPrivate> p;
}

template<typename T>
class MatrixBoxImpl : public MatrixBoxPrivate
{
cv::Mat_<T> m_matrix;
// ...
}
snb
snb
So if the base class is Q_OBJECT do signals work?

last day (15 days later) »