Template specialization not working for const double *

J

Justin S Bayer

Hi group,

I have a template that generates an abstract class, from which I want
to derive new classes which are supposed to implement the abstract
method. This somehow works in the following example:

http://codepad.org/UXl4jQLF

Thing is, I want my method T to work on const objects of the given
type. (Note: I don't want that to be part of the type that I am
specializing for.). So I just put in const everywhere, but it stops
working then:

http://codepad.org/lcy0kDMw

It tells me, that my new class is still abstract - although I have
overwritten the abstract method.

Even more funny, this works perfectly if I use double instead of
double*:

http://codepad.org/7biadxx3

Any help on how I can get the desired behaviour (specializing for
double*, being able to overwrite methods that use this type in
combination with const) and/or explanations why this is not working as
I'd expect it, are greatly appreciated!


-Justin

PS: Tried to google for this - somehow difficult to get the right
query string there, also checked the C++ FAQ Lite. Sorry if this comes
up frequently.
 
G

gob00st

Hi group,

I have a template that generates an abstract class, from which I want
to derive new classes which are supposed to implement the abstract
method. This somehow works in the following example:

http://codepad.org/UXl4jQLF

Thing is, I want my method T to work on const objects of the given
type. (Note: I don't want that to be part of the type that I am
specializing for.). So I just put in const everywhere, but it stops
working then:

http://codepad.org/lcy0kDMw

It tells me, that my new class is still abstract - although I have
overwritten the abstract method.

Even more funny, this works perfectly if I use double instead of
double*:

http://codepad.org/7biadxx3

Any help on how I can get the desired behaviour (specializing for
double*, being able to overwrite methods that use this type in
combination with const) and/or explanations why this is not working as
I'd expect it, are greatly appreciated!

-Justin

PS: Tried to google for this - somehow difficult to get the right
query string there, also checked the C++ FAQ Lite. Sorry if this comes
up frequently.

You can get your desired behaviour by adding a partial specialization
after primary template:

template <typename SampleType>
class Generic<SampleType*>
{
public:

void outer(const SampleType* sample)
{
this->inner(sample);
};

virtual void inner(const SampleType* sample)
{
std::cout << "processing for SampleType* " << std::endl;
}
};

This Works with VC++ 8.
Results: processing for double*

Gob00st
 
P

puzzlecracker

template <typename SampleType>
class Generic<SampleType*>
{
public:

        void outer(const SampleType* sample)
        {
                this->inner(sample);
        };

        virtual void inner(const SampleType* sample)
        {
                std::cout << "processing for SampleType* " << std::endl;
        }

};


How is it partial specialization since type is not known. From my
understanding, partial specialization is when one of the types is
know. In this case, we only know that only pointer type will be used.

Generic<double> gen; will create an instance of the template class
with double *.

Correct me if I am wrong.


Thanks
 
P

puzzlecracker

It just is.

 > From my



No.  Generic<double> will create an instance of the template class with
'double'.  Generic<double*> will create an instance of the
specialisation with 'SamepleType' == double.




Correct yourself, will you?  Write a program that has a general
(non-specialised) template and its partial specialisation for pointers
to any type.  Then instantiate it with 'int' and with 'int*', and see
which one is used in what case.

Argh, I see, totally misunderstood it. I thought the inclusion of a
pointer as part of template means that the type will be promoted to
pointer type. Instead, it means that that instantiation is only legal
when the pointer type is passed as a parameter, and it cannot accept
other non-pointer types, unless we have a non-specialized version

Thanks
 
B

Bo Persson

puzzlecracker said:
How is it partial specialization since type is not known.

That's why it is a partial specialization - it is known to be a
pointer type, not just any type.
From my
understanding, partial specialization is when one of the types is
know.

That's more like a full specialization.


Bo Persson
 
T

Triple-DES

That's more like a full specialization.

I believe puzzlecracker was thinking of something like

template<typename T, typename U>
struct C;
template<typename T>
struct C<T,int>;

Which is a common form of partial template specialization.
 
J

James Kanze

I have a template that generates an abstract class, from which
I want to derive new classes which are supposed to implement
the abstract method. This somehow works in the following
example:

Thing is, I want my method T to work on const objects of the
given type. (Note: I don't want that to be part of the type
that I am specializing for.). So I just put in const
everywhere, but it stops working then:

It tells me, that my new class is still abstract - although I
have overwritten the abstract method.

No you haven't. The abstract function takes double* as an
argument; the function in the derived class takes double const*.
Those are two different types.
Even more funny, this works perfectly if I use double instead
of double*:

That's because top-level const isn't part of the parameter type,
i.e.:
void f( double ) ;
void f( double const ) ;
declares the same function, twice, and
void g( double* ) ;
void g( double const* ) ;
declares two different functions. (But
void h( double* ) ;
void h( double* const ) ;
would declare the same function twice.)

Follow the general rule of always putting the const after what
it modifies; then, if const is the last thing in the list, it is
ignored.
Any help on how I can get the desired behaviour (specializing
for double*, being able to overwrite methods that use this
type in combination with const) and/or explanations why this
is not working as I'd expect it, are greatly appreciated!

As was suggested, partial specialization might be what you're
looking for. (I'm not actually too sure what you're looking
for.)
 
I

i.albert.cheng

Hi group,

I have a template that generates an abstract class, from which I want
to derive new classes which are supposed to implement the abstract
method. This somehow works in the following example:

http://codepad.org/UXl4jQLF

Thing is, I want my method T to work on const objects of the given
type. (Note: I don't want that to be part of the type that I am
specializing for.). So I just put in const everywhere, but it stops
working then:

http://codepad.org/lcy0kDMw

It tells me, that my new class is still abstract - although I have
overwritten the abstract method.

Even more funny, this works perfectly if I use double instead of
double*:

http://codepad.org/7biadxx3

Any help on how I can get the desired behaviour (specializing for
double*, being able to overwrite methods that use this type in
combination with const) and/or explanations why this is not working as
I'd expect it, are greatly appreciated!

-Justin

PS: Tried to google for this - somehow difficult to get the right
query string there, also checked the C++ FAQ Lite. Sorry if this comes
up frequently.

Apart the partial specialization solution that I suggested above,
there is actually a second solution, change your derived class Double
a bit into this :
class Doubled : public Generic<double*>
{
public:

virtual void inner( double* const sample)//#parameter changed here ,
so that this function actually override the abstract one in base class
{
std::cout << "processing for double* " << std::endl;
}
};

Test passed under VC++ 8.

Gob00st
 
I

i.albert.cheng

Hi group,

Thing is, I want my method T to work on const objects of the given
type. (Note: I don't want that to be part of the type that I am
specializing for.). So I just put in const everywhere, but it stops
working then:

At last, your idea of let T work on const objects is not entirely
correct.
Because you use it as a parameter of function outer like this in your
primary template:
template<typename SampleType>
class Generic
{
public:

void outer(const SampleType sample)
{
this->inner(sample);
};

virtual void inner(const SampleType sample) = 0;

};

If SampleType used to instantiate the template is not a pointer or
reference type, this const here is useless and error prone(Actually
that's one of the reason incurs this whole issue of this thread).
So I suggest you remove const from your primary template and add a
const pointer/reference partial specialization verion as I did above.

Gob00st
 
P

puzzlecracker

I believe puzzlecracker was thinking of something like

template<typename T, typename U>
struct C;
template<typename T>
struct C<T,int>;

Which is a common form of partial template specialization.

Almost, I was thinking of the following:

template<typename T, typename U>
struct C;

template<typename T, typename U>
struct C<T,int>;
 
N

Noah Roberts

puzzlecracker said:
Almost, I was thinking of the following:

template<typename T, typename U>
struct C;

template<typename T, typename U>
struct C<T,int>;
That's not valid. You have to use all the types in the specialization.

struct C<T,sometemp<U> > would be ok. What you have is not.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top