const parameters to template class member functions

K

Kenneth Massey

I have run into a peculiar problem, in which the following sample code
does not compile (gcc 3.3). I have a template class with a member
function that should take a const version of the template parameter.
However, when I try to use the class with (T=int*), the compiler seems
to ignore the const and gives an error if I pass a const int*. Any
help would be much appreciated.

Kenneth

// test.cpp: In function `int main()':
// test.cpp: error: invalid conversion from `const int*' to
`int*'
// test.cpp: error: initializing argument 1 of `int
myclass<T>::check(T)



#include <stdio.h>

template<class T>
class myclass {
T x;
public:
myclass(T x0):x(x0) {}

int check(const T y) { return x==y; }

// compiles fine with this line: T is explicitly replaced by int*
// int check(const int* y) { return x==y; }
};

int main() {
int k;
myclass<int*> mc(&k); // T = int*

const int* p = &k;

printf("%d\n",mc.check(p)); // calling check() causes the error

return 0;
}
 
R

Rolf Magnus

Kenneth said:
I have run into a peculiar problem, in which the following sample code
does not compile (gcc 3.3). I have a template class with a member
function that should take a const version of the template parameter.
However, when I try to use the class with (T=int*), the compiler seems
to ignore the const and gives an error if I pass a const int*. Any
help would be much appreciated.

int check(const T y) { return x==y; }

For T = int*, y is a constant pointer to a non-constant int.
// compiles fine with this line: T is explicitly replaced by int*
// int check(const int* y) { return x==y; }

In this case, y is a non-constant pointer to constant int.
 
K

Kenneth Massey

Makes sense.

Is there any way to get the latter behavior, definint the function with the
template parameter instead of hard coding int* ?

Thanks
 
J

JKop

Kenneth Massey posted:
Makes sense.

Is there any way to get the latter behavior, definint the function with
the template parameter instead of hard coding int* ?


#include <stdio.h>

template<class T>
class myclass {
T x;
public:
myclass(T x0):x(x0) {}

int check(T y) { return x==y; }

// compiles fine with this line: T is explicitly replaced
by int*
// int check(const int* y) { return x==y; }
};

int main() {
int k;
myclass<const int*> mc(&k); // T = int*

const int* p = &k;

printf("%d\n",mc.check(p)); // calling check() causes
the error

return 0;
}


-JKop
 
V

Victor Bazarov

Kenneth said:

Please don't top-post. I rearranged it.
Makes sense.

Is there any way to get the latter behavior, definint the function with the
template parameter instead of hard coding int* ?

If you don't mind hard-coding T*, then

int check(T const *y) ...

and substitute 'T' with 'int' (the pointer bit is already accounted for).

Otherwise, consider a simple fact that 'const' and types should be always
placed in a particular order to understand how type substitution works:

int check(T const y) // const goes _after_ the type

Now, even if you replace 'T' with 'int*', you get

int check(int* const y) // easier to understand, isn't it?

.. To get the same thing as

int check(int const *y)

you need to make your 'T' 'int const*'.

Also remember that top-level consts do not really count (or do anything
useful):

int check(int* const y)

is really quite equivalent to

int check(int* y)

V
 
J

John Harrison

Kenneth Massey said:
Makes sense.

Is there any way to get the latter behavior, definint the function with the
template parameter instead of hard coding int* ?

Something like this (untested) which uses partial template specialisation to
transform T* into const T*.

template <class T>
struct MakeConstPointer
{
typedef T type;
};

template <class T>
struct MakeConstPointer<T*>
{
typedef const T* type;
};

template <class T>
struct MakeConstPointer<const T*>
{
typedef const T* type;
};

template<class T>
class myclass {
T x;
public:
myclass(T x0):x(x0) {}

int check(typename MakeConstPointer<T>::type y) { return x==y; }
};

Of course your compiler must support partial template specialisation, which
all modern compilers do.

john
 

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

Forum statistics

Threads
474,172
Messages
2,570,934
Members
47,477
Latest member
ColumbusMa

Latest Threads

Top