By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,413 Members | 996 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,413 IT Pros & Developers. It's quick & easy.

YA Template specialization question

P: n/a
Hi all,

I just started to mess around with templates. First I declared a class
Image as follows(this is a small version of the real thing which is
pretty big):

template<int depth, int space, int channel>
class Image {

// Ctor/Dtor.
....

//Operators

Image& operator|= (const Image& pImage);

Image& operator|= (const Image<depth,space,1>& pImage);

....
};

The main reason I use non-type parameters is to enforce compile time
errors for illegal operations on Image types (defined by me), e.g. I
only want to allow an |= operator to act on exactly same type Images OR
with rhs Image with channel = 1. I understand there might be other ways
of doing this but first I want to get accustomed to the template
mechanism.

Naturally this first version is not a good idea. The compiler complains
when an Image of type
Image<somevalue,somevalue,1> is instantiated. Both signatures of the |=
operator become same and hence the legit complaint.

So i decided to use template specialization. The updated version of the
class now is:

template<int depth, int space, int channel>
class Image {

// Ctor/Dtor.
....

//Operators

template<int t> Image& operator|= (const Image<depth,space,t>& pImage);

....
};

template<int d,int s,int c>
template<int t>
Image<d,s,c>&
Image<d,s,c>::operator|= (const Image<d,s,t>& pImage) {
...
return *this;
}

//::-------------------------------------------------------------------
template<int d,int s,int c>
template<>
Image<d,s,c>&
Image<d,s,c>::operator|=<1>(const Image<d,s,1>& pImage) {
...
return *this;
}

...but now I am hit by C2244:"unable to match function definition to an
existing declaration definition" in my VC 8.0.

I tried to troubleshoot by google and usenet and found LOTS of posts.
They talk about partial specialization, about the standard not allowing
member funtion template specialization without enclosing class
specialization first etc. But mainly people complain about VC's
non-standard behaviour with template specializations. Nevertheless i
wasn't able to find any complain with VC 8.0 so i am not quiet sure if
this is still the issue or it is my fault (which I highly expect).

Can I use your expertise on the topic? Is it me? Or VC?

Thank you.

Murat

Jun 19 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
me****@gmail.com wrote:
[..]
//::-------------------------------------------------------------------
template<int d,int s,int c>
template<>
Image<d,s,c>&
Image<d,s,c>::operator|=<1>(const Image<d,s,1>& pImage) {
...
return *this;
}
You're not allowed to specialize a member template without *first*
initializing the class template itself.

You will either need to redesign or overload.
..but now I am hit by C2244:"unable to match function definition to an
existing declaration definition" in my VC 8.0.
[..]


V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 19 '06 #2

P: n/a
Victor Bazarov wrote:
me****@gmail.com wrote:
[..]
//::-------------------------------------------------------------------
template<int d,int s,int c>
template<>
Image<d,s,c>&
Image<d,s,c>::operator|=<1>(const Image<d,s,1>& pImage) {
...
return *this;
}


You're not allowed to specialize a member template without *first*
initializing the class template itself.

You will either need to redesign or overload.
..but now I am hit by C2244:"unable to match function definition to an
existing declaration definition" in my VC 8.0.
[..]


V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


Thanks for the help.

I decided to use a simple trick without going into specializations.

Basically the new class looks like this:

template<int a, int b, int c>
class Image {

public:

template<int t> Image& operator |= (const Image<a,b,t>& pImage) {
_isUniChannel(pImage);
...
}

private:

void _isUniChannel(Image<a,b,1>& pImage) {}
};
....and yes this allows compile time error for incompatible Image
"types" in the given operation.

This is one of the solutions that I came up with. I am open to comments.

Jun 20 '06 #3

P: n/a
me****@gmail.com wrote:
Victor Bazarov wrote:
me****@gmail.com wrote:
[..]
//::-------------------------------------------------------------------
template<int d,int s,int c>
template<>
Image<d,s,c>&
Image<d,s,c>::operator|=<1>(const Image<d,s,1>& pImage) {
...
return *this;
}


You're not allowed to specialize a member template without *first*
initializing the class template itself.

You will either need to redesign or overload.
..but now I am hit by C2244:"unable to match function definition to
an existing declaration definition" in my VC 8.0.
[..]


V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


Thanks for the help.

I decided to use a simple trick without going into specializations.

Basically the new class looks like this:

template<int a, int b, int c>
class Image {

public:

template<int t> Image& operator |= (const Image<a,b,t>& pImage) {
_isUniChannel(pImage);
...
}

private:

void _isUniChannel(Image<a,b,1>& pImage) {}
};
...and yes this allows compile time error for incompatible Image
"types" in the given operation.

This is one of the solutions that I came up with. I am open to
comments.


I wonder, if your purpose was to prohibit the use of operator |= with
any types that don't have the third template argument ==1, then why
not just define

Image& operator |= (const Image<a,b,1>& pImage) {
...
}

? Doesn't it serve the same purpose?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 20 '06 #4

P: n/a
Victor Bazarov wrote:
me****@gmail.com wrote:
Victor Bazarov wrote:
me****@gmail.com wrote:
[..]
//::-------------------------------------------------------------------
template<int d,int s,int c>
template<>
Image<d,s,c>&
Image<d,s,c>::operator|=<1>(const Image<d,s,1>& pImage) {
...
return *this;
}

You're not allowed to specialize a member template without *first*
initializing the class template itself.

You will either need to redesign or overload.

..but now I am hit by C2244:"unable to match function definition to
an existing declaration definition" in my VC 8.0.
[..]

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


Thanks for the help.

I decided to use a simple trick without going into specializations.

Basically the new class looks like this:

template<int a, int b, int c>
class Image {

public:

template<int t> Image& operator |= (const Image<a,b,t>& pImage) {
_isUniChannel(pImage);
...
}

private:

void _isUniChannel(Image<a,b,1>& pImage) {}
};
...and yes this allows compile time error for incompatible Image
"types" in the given operation.

This is one of the solutions that I came up with. I am open to
comments.


I wonder, if your purpose was to prohibit the use of operator |= with
any types that don't have the third template argument ==1, then why
not just define

Image& operator |= (const Image<a,b,1>& pImage) {
...
}

? Doesn't it serve the same purpose?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


I had to be more complete with the code:

template<int a, int b, int c>
class Image {

public:

// This is called when rhs of |= has t != c
template<int t> Image& operator |= (const Image<a,b,t>& pImage) {
_isUniChannel(pImage);
...
}

// This is called when both rhs and lhs have the same type.
Image& operator |= (const Image& pImage) {
...
}

private:

void _isUniChannel(Image<a,b,1>& pImage) {}
};

I want the |= operator defined for only when rhs has the same type as
lhs OR rhs is single channel and both remaining non-types the same as
lhs.

Jun 20 '06 #5

P: n/a
me****@gmail.com wrote:
Victor Bazarov wrote:
me****@gmail.com wrote:
Victor Bazarov wrote:
me****@gmail.com wrote:
> [..]
> //::-------------------------------------------------------------------
> template<int d,int s,int c>
> template<>
> Image<d,s,c>&
> Image<d,s,c>::operator|=<1>(const Image<d,s,1>& pImage) {
> ...
> return *this;
> }

You're not allowed to specialize a member template without *first*
initializing the class template itself.

You will either need to redesign or overload.

> ..but now I am hit by C2244:"unable to match function definition
> to an existing declaration definition" in my VC 8.0.
> [..]

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Thanks for the help.

I decided to use a simple trick without going into specializations.

Basically the new class looks like this:

template<int a, int b, int c>
class Image {

public:

template<int t> Image& operator |= (const Image<a,b,t>& pImage) {
_isUniChannel(pImage);
...
}

private:

void _isUniChannel(Image<a,b,1>& pImage) {}
};
...and yes this allows compile time error for incompatible Image
"types" in the given operation.

This is one of the solutions that I came up with. I am open to
comments.


I wonder, if your purpose was to prohibit the use of operator |= with
any types that don't have the third template argument ==1, then why
not just define

Image& operator |= (const Image<a,b,1>& pImage) {
...
}

? Doesn't it serve the same purpose?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


I had to be more complete with the code:

template<int a, int b, int c>
class Image {

public:

// This is called when rhs of |= has t != c
template<int t> Image& operator |= (const Image<a,b,t>& pImage) {
_isUniChannel(pImage);
...
}

// This is called when both rhs and lhs have the same type.
Image& operator |= (const Image& pImage) {
...
}

private:

void _isUniChannel(Image<a,b,1>& pImage) {}
};

I want the |= operator defined for only when rhs has the same type as
lhs OR rhs is single channel and both remaining non-types the same as
lhs.


OK. What would happen when both lhs and rhs objects are the same and of
Image<a,b,1> type? I guess the non-template version should be picked up
for overload resolution...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 20 '06 #6

P: n/a
Victor Bazarov wrote:
me****@gmail.com wrote:
Victor Bazarov wrote:
me****@gmail.com wrote:
Victor Bazarov wrote:
> me****@gmail.com wrote:
>> [..]
>> //::-------------------------------------------------------------------
>> template<int d,int s,int c>
>> template<>
>> Image<d,s,c>&
>> Image<d,s,c>::operator|=<1>(const Image<d,s,1>& pImage) {
>> ...
>> return *this;
>> }
>
> You're not allowed to specialize a member template without *first*
> initializing the class template itself.
>
> You will either need to redesign or overload.
>
>> ..but now I am hit by C2244:"unable to match function definition
>> to an existing declaration definition" in my VC 8.0.
>> [..]
>
> V
> --
> Please remove capital 'A's when replying by e-mail
> I do not respond to top-posted replies, please don't ask

Thanks for the help.

I decided to use a simple trick without going into specializations.

Basically the new class looks like this:

template<int a, int b, int c>
class Image {

public:

template<int t> Image& operator |= (const Image<a,b,t>& pImage) {
_isUniChannel(pImage);
...
}

private:

void _isUniChannel(Image<a,b,1>& pImage) {}
};
...and yes this allows compile time error for incompatible Image
"types" in the given operation.

This is one of the solutions that I came up with. I am open to
comments.

I wonder, if your purpose was to prohibit the use of operator |= with
any types that don't have the third template argument ==1, then why
not just define

Image& operator |= (const Image<a,b,1>& pImage) {
...
}

? Doesn't it serve the same purpose?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


I had to be more complete with the code:

template<int a, int b, int c>
class Image {

public:

// This is called when rhs of |= has t != c
template<int t> Image& operator |= (const Image<a,b,t>& pImage) {
_isUniChannel(pImage);
...
}

// This is called when both rhs and lhs have the same type.
Image& operator |= (const Image& pImage) {
...
}

private:

void _isUniChannel(Image<a,b,1>& pImage) {}
};

I want the |= operator defined for only when rhs has the same type as
lhs OR rhs is single channel and both remaining non-types the same as
lhs.


OK. What would happen when both lhs and rhs objects are the same and of
Image<a,b,1> type? I guess the non-template version should be picked up
for overload resolution...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


Exactly..which is what I want.

Now the problem is the interpretation (from the user viewpoint) of the
cryptic compiler error messages when Image types do not match.

Jun 20 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.