const parameters to template class member functions 
July 22nd, 2005, 05:38 PM
| | | |
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;
} | 
July 22nd, 2005, 05:38 PM
| | | | 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. | 
July 22nd, 2005, 05:38 PM
| | | | 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] | 
July 22nd, 2005, 05:38 PM
| | | | 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 | 
July 22nd, 2005, 05:38 PM
| | | | 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 | 
July 22nd, 2005, 05:38 PM
| | | | 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 |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 225,662 network members.
|