Hanz0
Hanz0

Reputation: 59

Using templates as template function argument

Hi everybody!

I'm starting to learn about templates in C++, so sorry if the question is too simple =P

I'm trying to write a function like this:

template< template<typename> class C, typename T>
void bRedChannel(C<T> src, C<T> out)
{
    // do something
}

and I'm trying to call the function this way:

Mat_<uchar> roi = image(Rect(10, 10, rows, cols));
Mat_<uchar> masked;
bRedChannel< Mat_<uchar>, uchar >(roi, masked);

that results in the error

no matching function for call to ‘bRedChannel(cv::Mat_<unsigned char>&, cv::Mat_<unsigned char>&)´

What's wrong?

Update:

Here's the code as it is now:

#include <cv.hpp>
#include <highgui/highgui.hpp>
#include <iostream>

using namespace cv;
using std::cout;
using std::endl;

template< template<typename> class C, typename T>
void bRedChannel(C<T> src, C<T> out)
{

    for (int i = 0; i < src.rows; i += 2)
    {
        for (int j = 0; j < src.cols; j += 2)
        {
            out(i, j) = src(i, j);
        }
    }
};

int main( int argc, char** argv )
{
  int rows = 512, cols = 512;

  Mat_<uchar> image = imread("Autumn-Desktop.jpg", CV_LOAD_IMAGE_GRAYSCALE);
  Mat_<uchar> roi = image(Rect(10, 10, rows, cols));
  image.release();

  Mat_<uchar> masked;
  bRedChannel(roi, masked);

  namedWindow( "Result" );
  imshow( "Result", masked );

  waitKey(0);

  imwrite("teste.png", masked);

  return 0;
}

It runs now, but it is interrupted. The problem may be with the algorithm now, but my question was answered! Thanks @RSahu!

Upvotes: 0

Views: 79

Answers (1)

R Sahu
R Sahu

Reputation: 206567

Instead of

bRedChannel< Mat_<uchar>, uchar >(roi, masked);
            // ^^^^^^^^^ 

use

bRedChannel< Mat_, uchar >(roi, masked);

As a rule, prefer not to explicitly use the typenames when invoking a function template. The compiler should be able to deduce the typenames. Use the explicit typenames only if the compiler cannot deduce the typenames or you want to use different typenames than what the compiler deduces.

Use

bRedChannel(roi, masked);

Use the typenames explicitly only if necessary.

Additional Feedback

You have:

template< template<typename> class C, typename T>
void bRedChannel(C<T> src, C<T> out)
{

    for (int i = 0; i < src.rows; i += 2)
    {
        for (int j = 0; j < src.cols; j += 2)
        {
            out(i, j) = src(i, j);
        }
    }
};

and you are using it with:

  Mat_<uchar> masked;
  bRedChannel(roi, masked);

You are modifying a local copy of masked in bRedChannel. Those modifications have no effect on masked in main. The first argument to bRedChannel also makes a copy of the input argument. It could be made fore efficient by changing the type to C<T> const&.

I would suggest changing bRedChannel to:

template< template<typename> class C, typename T>
void bRedChannel(C<T> const& src, C<T>& out)
{

    for (int i = 0; i < src.rows; i += 2)
    {
        for (int j = 0; j < src.cols; j += 2)
        {
            out(i, j) = src(i, j);
        }
    }
};

Upvotes: 4

Related Questions