 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Kenneth Massey Guest
|
Posted: Mon Jul 19, 2004 9:08 pm Post subject: const parameters to template class member functions |
|
|
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
#include <stdio.h>
template<class T>
class myclass {
T x;
public:
myclass(T x0) (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;
// test.cpp: In function `int main()':
// test.cpp:25: error: invalid conversion from `const int*' to
`int*'
// test.cpp:25: error: initializing argument 1 of `int
myclass<T>::check(T)
printf("%dn",mc.check(p));
return 0;
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
Tobias Güntner Guest
|
Posted: Tue Jul 20, 2004 7:56 am Post subject: Re: const parameters to template class member functions |
|
|
Kenneth Massey wrote:
| Quote: | template
class myclass {
T x;
public:
myclass(T x0) (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; }
};
|
I think the problem is the const T y. With T = int* this becomes
int*const, i.e. a _constant pointer_ to a _non-const integer_. Since a
pointer to a const int cannot be converted into a pointer to non-const
(without a type cast, that is ), the compiler generates an error.
For example, you could create a second template parameter (one for int*
and another for const int*) or you could simply pass an int for T and
declare your function as int check(const T*).
Regards,
Tobias
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Tue Jul 20, 2004 8:14 am Post subject: Re: const parameters to template class member functions |
|
|
[email]eigenmaster (AT) yahoo (DOT) com[/email] (Kenneth Massey) writes:
| Quote: | 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.
|
If 'T' is a name for 'int *', 'const T' (and 'T const', for that matter) is
a name for 'int * const'; i.e. the pointer is const, not the int pointed to.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Daniel Krügler (ne Spange Guest
|
Posted: Tue Jul 20, 2004 6:12 pm Post subject: Re: const parameters to template class member functions |
|
|
Good morning Kenneth Massey,
Kenneth Massey schrieb:
| Quote: | 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
#include <stdio.h
template
class myclass {
T x;
public:
myclass(T x0) (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; }
};
Please note that any template member functions are not automatically |
instantiated. You have to
distinguish the point of definition of the template (non-standard
nomenclature) from the actual point of
instantiation (aka POI, just before main in your example).
| Quote: | int main() {
int k;
myclass
const int* p = &k;
// test.cpp: In function `int main()':
// test.cpp:25: error: invalid conversion from `const int*' to
`int*'
// test.cpp:25: error: initializing argument 1 of `int
myclass<T>::check(T)
printf("%dn",mc.check(p));
return 0;
}
Since myclass<int*> does contain an int* member, you are effectivly |
trying to
perform a code similar to:
const int* p = &k;
int* x = p;
in your call of ms.check(). This obviously leads to a violation of
constness contraints.
Hope that helps,
Daniel Krügler
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
Maxim Yegorushkin Guest
|
Posted: Tue Jul 20, 2004 6:26 pm Post subject: Re: const parameters to template class member functions |
|
|
Thomas Maeder <maeder (AT) glue (DOT) ch> wrote:
| Quote: | eigenmaster (AT) yahoo (DOT) com (Kenneth Massey) writes:
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.
If 'T' is a name for 'int *', 'const T' (and 'T const', for that matter) is
a name for 'int * const'; i.e. the pointer is const, not the int pointed to.
|
I think putting cv-qualifier before the type is a common source of confusion. Had the OP put const after the type he would likely have not made that error. Is not it a good motivation for always putting cv-qualifiers after the type?
--
Maxim Yegorushkin
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ben Hutchings Guest
|
Posted: Tue Jul 20, 2004 9:35 pm Post subject: Re: const parameters to template class member functions |
|
|
[Not posted to comp.std.c++ as it is off-topic there.]
Kenneth Massey wrote:
| Quote: |
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.
snip |
When T is int *, const T is int * const and not const int *. See
<http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.5>.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Tue Jul 20, 2004 9:57 pm Post subject: Re: const parameters to template class member functions |
|
|
"Maxim Yegorushkin" <e-maxim (AT) yandex (DOT) ru> writes:
| Quote: | If 'T' is a name for 'int *', 'const T' (and 'T const', for that matter) is
a name for 'int * const'; i.e. the pointer is const, not the int pointed to.
I think putting cv-qualifier before the type is a common source of
confusion. Had the OP put const after the type he would likely have not
made that error. Is not it a good motivation for always putting
cv-qualifiers after the type?
|
I agree.
But as long as (otherwise) excellent C++ texts such as
"The C++ Programming Language" and the ISO C++ Standard write const on the
left, we have to be able to deal with that even if we ourselves write const
on the right.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
dietmar_kuehl@yahoo.com Guest
|
Posted: Wed Jul 21, 2004 11:55 am Post subject: Re: const parameters to template class member functions |
|
|
Hi,
Kenneth Massey wrote:
| Quote: | 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*.
|
This is essentially a problem of 'const' placement - or, at least, the
problem would have been immediately obvious if you had placed the
'const' to the right rather than to the left (obviously, there is just
one right 'const' placement : 'const int*' is equivalent to
'int const*'. ... and 'const T' is equivalent to 'T const'. If you now
replace 'T' by 'int*' you do not get 'const int*' but rather 'int*
const':
these two types are obviously not identical.
I think there shall be warnings about the non-right 'const' placement
(except in 'extern "C"' sections - it is my understanding that C only
support the non-right placement).
--
<mailto:dietmar_kuehl (AT) yahoo (DOT) com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gareth Stockwell Guest
|
Posted: Wed Jul 21, 2004 3:26 pm Post subject: Re: const parameters to template class member functions |
|
|
[email]eigenmaster (AT) yahoo (DOT) com[/email] (Kenneth Massey) wrote in message news:<ac2b2aa1.0407190619.72a68f9d (AT) posting (DOT) google.com>...
| Quote: | 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.
template<class T
class myclass {
T x;
public:
myclass(T x0) (x0) {}
int check(const T y) { return x==y; }
};
|
Kenneth,
I think that what is happening here is that, given the signature
int check(const T);
with T=int*, upon instantiation the compiler is generating
int check(T* const);
rather than (as you want)
int check(const T*);
I can think of two solutions:
1. If you know that T will always be some kind of pointer, then
re-write the template such that T is the value type, rather than the
pointer type (so here, T=int). Then you can write the signature of
check directly:
int check(const T*);
2. More generally, I think you can get around the problem with a bit
of template metaprogramming. Basically you need a structure which
converts T to const T and gets the asterix in the correct place...
template
struct MakeConst
{ typedef const Type result; };
template<typename Type>
struct MakeConst<Type*>
{ typedef const Type* result; };
Now you can write:
int check(typename MakeConst<T>::result);
Gareth
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
Tokyo Tomy Guest
|
Posted: Wed Jul 21, 2004 3:26 pm Post subject: Re: const parameters to template class member functions |
|
|
[email]eigenmaster (AT) yahoo (DOT) com[/email] (Kenneth Massey) wrote in message news:<ac2b2aa1.0407190619.72a68f9d (AT) posting (DOT) google.com>...
| Quote: | 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
#include <stdio.h
template
class myclass {
T x;
public:
myclass(T x0) (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
const int* p = &k;
// test.cpp: In function `int main()':
// test.cpp:25: error: invalid conversion from `const int*' to
`int*'
// test.cpp:25: error: initializing argument 1 of `int
myclass<T>::check(T)
printf("%dn",mc.check(p));
return 0;
}
|
My MSVC++6 also issured the same error just as above. The
interpretation of the error seems to be easy as follows.
1. "const T y" in the check argument is converted to "T const y", just
like, for example,"const int i" is equivalent to "int const i".
2. T = int*, so the check argument becomes "int* const y" (const
pointer to int).
After I replaced "const int* p = &k;" with "int* const p = &k;", the
code compiled with my MSVC++6.
However, I just wander you can agree with this behavior.
How can you do if you want the check argument to be "const int*" to
accept the original p in the above code.
Following is one solution, but T x becomes pointer to const int as an
(probably) undesirable side effect.
#include <stdio.h>
template<class T>
class myclass {
T x;
public:
myclass(T x0) (x0) {}
int check(T y) { return x==y; }
};
int main() {
int k;
myclass<const int*> mc(&k); // T = const int*
const int* p = &k; // same as in the orginal code
printf("%dn",mc.check(p));
return 0;
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
Jozef Saniga Guest
|
Posted: Wed Jul 21, 2004 3:26 pm Post subject: Re: const parameters to template class member functions |
|
|
Hi,
Kenneth Massey wrote:
| Quote: | 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.
The compiler does not ignore the const. The const is there just not |
where you expect it to be.
| Quote: | Kenneth
#include <stdio.h
template
class myclass {
T x;
public:
myclass(T x0) (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; }
When myclass is instantiated for int* check becomes: |
int check (int* const y) { return x == y; }
since 'const T y' says that y is of type T and y is const. So y is of
type int* and it is const. Note that y is const not the int y points to.
Try to compile this piece of code that has a very similar problem:
int main ()
{
typedef int* T;
const T y;
y = 1;
return 0;
}
| Quote: | };
int main() {
int k;
myclass
const int* p = &k;
// test.cpp: In function `int main()':
// test.cpp:25: error: invalid conversion from `const int*' to
`int*'
// test.cpp:25: error: initializing argument 1 of `int
myclass<T>::check(T)
printf("%dn",mc.check(p));
return 0;
}
|
Jozef
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
Ulrich Eckhardt Guest
|
Posted: Wed Jul 21, 2004 3:26 pm Post subject: Re: const parameters to template class member functions |
|
|
Kenneth Massey wrote:
| Quote: | 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.
#include
template
class myclass {
T x;
public:
myclass(T x0) (x0) {}
int check(const T y) { return x==y; }
^^^ *ouch* |
Don't do that in examples, your real code might have valid reasons to do
so, but not examples.
| Quote: | // compiles fine with this line: T is explicitly replaced by int*
// int check(const int* y) { return x==y; }
|
Yes, but that's something different: assuming T='int*', you have one 'int
const*' and one 'int * const'. If that makes no sense to you, just read
the FAQ, it's explained there.
Uli
--
Questions ?
see C++-FAQ Lite: http://parashift.com/c++-faq-lite/ first !
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
vze2hb3b@verizon.net Guest
|
Posted: Wed Jul 21, 2004 3:26 pm Post subject: Re: const parameters to template class member functions |
|
|
In comp.lang.c++.moderated Kenneth Massey <eigenmaster (AT) yahoo (DOT) com> wrote:
| Quote: |
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
#include <stdio.h
template
class myclass {
T x;
public:
myclass(T x0) (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
const int* p = &k;
|
Hi! The problem is that T is int *, so const T translates
to int * const (constant pointer), not to const int *
(pointer to constant integer). If you define p as
int * const p = &k;
then the compiler should be happy.
Best,
Alexander
| Quote: |
// test.cpp: In function `int main()':
// test.cpp:25: error: invalid conversion from `const int*' to
`int*'
// test.cpp:25: error: initializing argument 1 of `int
myclass<T>::check(T)
printf("%dn",mc.check(p));
return 0;
}
|
--
Aleksandr Morgulis
[email]aleksandr.morgulis (AT) verizon (DOT) net[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
Jeffrey Lau Guest
|
Posted: Wed Jul 21, 2004 3:26 pm Post subject: Re: const parameters to template class member functions |
|
|
The problem is the placement of the const in the declaration of 'p':
| Quote: | int k;
myclass<int*> mc(&k); // T = int*
const int* p = &k;
|
If 'T' is 'int*', then 'const T' is 'int* const'; the constant version
of 'int*'. This is perhaps why most template code I have seen will use
'T const' instead of 'const T'. I have also adopted this declaration
style for all const variables in code:
int const constantInt(5);
char const* const constantPointerToConstantChar("Blah");
This allows you to read from right to left exactly the type of the
variable.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
Alberto Barbati Guest
|
Posted: Wed Jul 21, 2004 3:26 pm Post subject: Re: const parameters to template class member functions |
|
|
Kenneth Massey wrote:
| Quote: | 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.
|
If you write
typedef int* T;
Then "const T" is "int* const" (a constant pointer to an int) which is
very different from "const int*" (a pointer to a constant int).
If you analyse your code you will realize that it is a more complex case
of this simple issue.
Alberto
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|