Getting the type of parameters passed in the variable argument list

I wrote a function with a variable argument list

void cvShowMatImages( char* title, int nArgs, ...) // Mat Images 

where the argument for the transfer is an open-loop image. I actually have two different functions for the two image formats IplImage and Mat mentioned above and the second

 void cvShowIplImages( char* title, int nArgs, ...) // Ipl Images 

But I can’t mix two types of images. I could solve my problem if I could determine the type of the argument passed, but I do not know how to do it. This is how I read the argument:

 // Get the images passed as arguments va_list args; // Initialize the variable argument list va_start( args, nArgs ); // Loop on each image for ( int num = 0; num < nArgs; num++ ) { // Get the image to be copied from the argument list srcImg = va_arg( args, Mat ); ... 

and for IplImage:

 srcImg = va_arg( args, IplImage* ); 

In both cases, srcImg is declared as

 Mat srcImg 

since there is an overloaded operator = for IplImage. Is there any way to solve this problem?

+4
source share
3 answers

Using variadic templates in this way is a possible solution:

 #include <iostream> template<typename... Args> void func(double t, Args... args) ; template<typename... Args> void func(int t, Args... args) ; void func(int t) { std::cout << "int: "<< t << std::endl ; } void func(double t) { std::cout << "double: "<< t << std::endl ; } template<typename... Args> void func(double t, Args... args) { func(t) ; func(args...) ; } template<typename... Args> void func(int t, Args... args) { func(t) ; func(args...) ; } int main() { int x1 = 1, x2 = 5 ; double d1 = 2.5 , d2 = 3.5; func( x1 , d1, x2 ) ; func( x1 , d1, d2 ) ; } 

This is not very elegant, but can help solve your problem. Another method would be to use two std::initializer_list , one for each type, for example:

 #include <iostream> #include <initializer_list> void func2( std::initializer_list<int> listInt, std::initializer_list<double> listDouble ) { for( auto elem : listInt ) { std::cout << "Int: " << elem << std::endl ; } for( auto elem : listDouble ) { std::cout << "double: " << elem << std::endl ; } } int main() { func2( {10, 20, 30, 40 }, {2.5, 2.5 }) ; } 
+1
source

I would prefer to pass a tuple or an array or a vector.

Since std::array is a template with N, you can also make your function a template with N and implement it in general. The Variadic template is also viable if your compiler is good for it.

This is what we are trying to get rid of. This behavior is undefined to pass anything non-POD, and type checking is not possible. Which makes it too error prone. For your business, this is also not very useful.

0
source

First of all, I thank you all for your contribution!

I do not have a C ++ 11 compatible compiler, so some of your suggestions will not work.

Anyway, I found a fairly simple solution that I never thought to work! - which just returns an argument containing IplImage for Mat!

Example:

 cvShowMatImages( "all my Ipl and Mat images", 2, myMatImage, (Mat)myIplImage ); 
0
source

Source: https://habr.com/ru/post/1485069/


All Articles