Sparkofska
Sparkofska

Reputation: 1320

What is wrong with my template specialization?

I want to provide several conversion functions that transform my custom struct into other types. These functions should be overloaded by the return return type. I have tried template specialization like follows.

I get this compiler error message:

class cv::Rect __cdecl convert<class cv::Rect >(struct MyRect const &)" already defined in CallerCode.obj.

What is wrong with my code?

MyRect.h

struct MyRect
{
    float lux, luy, rlx, rly;

    float width() const;
    float height() const;
};

Library code

class cv::Rect;
struct OtherRect;

Conversion.h

template<typename T> T convert(const MyRect& r);

template<> cv::Rect convert<cv::Rect>(const MyRect& r)
{
    return cv::Rect(r.lux, r.luy, r.width(), r.height());
}

template<> OtherRect convert<OtherRect>(const MyRect& r)
{
    return OtherRect(r.lux, r.luy, r.rlx, r.rly);
}

Calling code

MyRect r{ 0.f, 0.f, 0.f, 0.f };
const cv::Rect cr = convert<cv::Rect>(r);

Upvotes: 1

Views: 55

Answers (1)

Jarod42
Jarod42

Reputation: 217085

Full specializations are no longer template functions, so no longer implicitly inline.

You have to add inline

template<> inline cv::Rect convert<cv::Rect>(const MyRect& r)
{
    return cv::Rect(r.lux, r.luy, r.width(), r.height());
}

or split declaration in header and definition in cpp file

// Declaration: in header
template<> cv::Rect convert<cv::Rect>(const MyRect&);
// Definition: in cpp file
template<> cv::Rect convert<cv::Rect>(const MyRect& r)
{
    return cv::Rect(r.lux, r.luy, r.width(), r.height());
}

Upvotes: 4

Related Questions