Connecting Tech Pros Worldwide Forums | Help | Site Map

const parameters to template class member functions

Kenneth Massey
Guest
 
Posts: n/a
#1: Jul 22 '05
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;
}


Rolf Magnus
Guest
 
Posts: n/a
#2: Jul 22 '05

re: const parameters to template class member functions


Kenneth Massey wrote:
[color=blue]
> 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.[/color]

[color=blue]
> int check(const T y) { return x==y; }[/color]

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

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

Kenneth Massey
Guest
 
Posts: n/a
#3: Jul 22 '05

re: const parameters to template class member functions


Makes sense.

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

Thanks
[color=blue][color=green]
>> int check(const T y) { return x==y; }[/color]
>
> For T = int*, y is a constant pointer to a non-constant int.
>[color=green]
>>
>> // compiles fine with this line: T is explicitly replaced by int*
>> // int check(const int* y) { return x==y; }[/color]
>
> In this case, y is a non-constant pointer to constant int.[/color]

JKop
Guest
 
Posts: n/a
#4: Jul 22 '05

re: const parameters to template class member functions


Kenneth Massey posted:
[color=blue]
> Makes sense.
>
> Is there any way to get the latter behavior, definint the[/color]
function with[color=blue]
> the template parameter instead of hard coding int* ?[/color]


#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
Victor Bazarov
Guest
 
Posts: n/a
#5: Jul 22 '05

re: const parameters to template class member functions


Kenneth Massey wrote:[color=blue]
> ...[/color]

Please don't top-post. I rearranged it.
[color=blue][color=green][color=darkred]
>>> int check(const T y) { return x==y; }[/color]
>>
>>For T = int*, y is a constant pointer to a non-constant int.
>>
>>[color=darkred]
>>> // compiles fine with this line: T is explicitly replaced by int*
>>> // int check(const int* y) { return x==y; }[/color]
>>
>>In this case, y is a non-constant pointer to constant int.[/color]
>
> Makes sense.
>
> Is there any way to get the latter behavior, definint the function with the
> template parameter instead of hard coding int* ?[/color]

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
John Harrison
Guest
 
Posts: n/a
#6: Jul 22 '05

re: const parameters to template class member functions



"Kenneth Massey" <kemassey@vt.edu> wrote in message
news:mjRKc.3073$_K2.192@lakeread02...[color=blue]
> Makes sense.
>
> Is there any way to get the latter behavior, definint the function with[/color]
the[color=blue]
> template parameter instead of hard coding int* ?[/color]

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


Closed Thread