Topic: const parameters to template class member functions
Author: hosoda@jtec.or.jp (Tokyo Tomy)
Date: Thu, 22 Jul 2004 22:59:22 +0000 (UTC) Raw View
hosoda@jtec.or.jp (Tokyo Tomy) wrote in message news:<49c1da0b.0407200131.998a680@posting.google.com>...
>...
> 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.
>
>...
(continued from my previous post)
Another and better solution is shown below. The lesson herein may be:
Be careful for the combination of pointer and const. When I came
across the solution, I began to think that the behavior ("const T y"
is converted to "T const y") easily brings errors, but is acceptable.
#include <stdio.h>
template<class T>
class myclass {
T* x;
public:
myclass(T* const x0):x(x0) {}
//int check(T y) { return x==y; }
int check(const T* y) { return x==y; }
};
int main() {
int k;
myclass<int> mc(&k); // T = int
const int* p = &k; // same as in the orginal code
printf("%d\n",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 ]
Author: eigenmaster@yahoo.com (Kenneth Massey)
Date: Mon, 19 Jul 2004 21:08:54 +0000 (UTC) Raw View
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):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;
// 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("%d\n",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 ]
Author: =?ISO-8859-1?Q?=22Daniel_Kr=FCgler_=28ne_Spangenberg=29=22?= <dsp@bdal.de>
Date: Tue, 20 Jul 2004 18:12:56 +0000 (UTC) Raw View
Good morning Kenneth Massey,
Kenneth Massey schrieb:
>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):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; }
>};
>
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).
>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("%d\n",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 ]
Author: Jozef Saniga <jsaniga@hotmail.com>
Date: Wed, 21 Jul 2004 15:26:10 +0000 (UTC) Raw View
Hi,
Kenneth Massey wrote:
> 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.
> Kenneth
>
>
> #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; }
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;
}
> };
>
> 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("%d\n",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 ]
Author: hosoda@jtec.or.jp (Tokyo Tomy)
Date: Wed, 21 Jul 2004 15:26:10 +0000 (UTC) Raw View
eigenmaster@yahoo.com (Kenneth Massey) wrote in message news:<ac2b2aa1.0407190619.72a68f9d@posting.google.com>...
> 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):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;
>
> // 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("%d\n",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):x(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("%d\n",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 ]
Author: gareth_stockwell@hotmail.com (Gareth Stockwell)
Date: Wed, 21 Jul 2004 15:26:10 +0000 (UTC) Raw View
eigenmaster@yahoo.com (Kenneth Massey) wrote in message news:<ac2b2aa1.0407190619.72a68f9d@posting.google.com>...
> 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):x(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<typename Type>
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 ]
Author: Ulrich Eckhardt <doomster@knuut.de>
Date: Wed, 21 Jul 2004 15:26:11 +0000 (UTC) Raw View
Kenneth Massey wrote:
> 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 <stdio.h>
>
> template<class T>
> class myclass {
> T x;
> public:
> myclass(T x0):x(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.
> // 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 ]
Author: vze2hb3b@verizon.net
Date: Wed, 21 Jul 2004 15:26:11 +0000 (UTC) Raw View
In comp.lang.c++.moderated Kenneth Massey <eigenmaster@yahoo.com> wrote:
>
> 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):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;
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
>
> // 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("%d\n",mc.check(p));
>
> return 0;
> }
--
Aleksandr Morgulis
aleksandr.morgulis@verizon.net
[ 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 ]
Author: Jeffrey Lau <moodhist@comcast.net>
Date: Wed, 21 Jul 2004 15:26:11 +0000 (UTC) Raw View
The problem is the placement of the const in the declaration of 'p':
> 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 ]
Author: Alberto Barbati <AlbertoBarbati@libero.it>
Date: Wed, 21 Jul 2004 15:26:12 +0000 (UTC) Raw View
Kenneth Massey wrote:
> 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 ]
Author: Christoph Schulz <kristov@arcor.de>
Date: Wed, 21 Jul 2004 19:59:07 +0000 (UTC) Raw View
Hello!
Kenneth Massey wrote:
> 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):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; }
> };
The problem is that "const T" is not "const int*" if the template is
instantiated with T=int*, but "int *const". That's similar to:
typedef int *T;
typedef const T CT;
Again, CT == "int *const" and *not* "const int*".
>
> 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("%d\n",mc.check(p));
>
Here the compiler tries to use myclass<int*>::check(int *const) and
fails to perform the needed and disallowed conversion "const int*" ==>
"int *const". Of course, if you define a suitable check(const int *),
the compiler error goes away. But again, this has nothing to do with
ignoring const.
Regards,
Christoph Schulz
[ 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 ]