Topic: Do template change the meaning of const?


Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1997/03/27
Raw View
Greg Silverman writes:

>     void g(const T& t) { }
>   const char* c = new char;
>   b.g(c);

> Formal argument of type char* const & in call to A<char*>::g(char* const
> &) is being passed const char*.

This means that the argument that should be of expected type
`char*const&' is being given an lvalue of type `char const*', so the
error message is correct, but a bit confusing.

> Uh? Why does it think the argument type is a "char* const &". I declared
> it as a "const char* &" through the template, but the compiler moved the
> placement of the const type-specifier. Why?

[const T&] is equivalent to [T const&] for any type T represented as a
single token, so, if T is char*, the type of g is function member of
A<char*> taking a reference to a constant pointer to char as argument.
If you intent do pass pointers to const char, you must use an instance
of A<const char*>.

--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
Universidade Estadual de Campinas, SP, Brasil

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu 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
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Greg Silverman <greg_silverman@smtp.svl.trw.com>
Date: 1997/03/22
Raw View
I am using the Solaris 4.1 compiler. I have come across the problem of
the const qualifier in templates having a special meaning. I shall
illustrate:

template <class T>
class A {
  public:
    void g(const T& t) { }
};

int main()
{
  A<char*> b;
  const char* c = new char;
  b.g(c); //(1)
}

The compiler complains about lines (1). It says

Formal argument of type char* const & in call to A<char*>::g(char* const
&) is being passed const char*.

Uh? Why does it think the argument type is a "char* const &". I declared
it as a "const char* &" through the template, but the compiler moved the
placement of the const type-specifier. Why?

--
Greg Silverman
TRW/SIG
Sunnyvale, Ca

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Bradd W. Szonye" <bradds@concentric.net>
Date: 1997/03/22
Raw View
Greg Silverman <greg_silverman@smtp.svl.trw.com> wrote in article
<fjh-970323-035812@cs.mu.oz.au>...
>
> template <class T>
> class A {
>   public:
>     void g(const T& t) { }
> };
>
> int main()
> {
>   A<char*> b;
>   const char* c = new char;
>   b.g(c); //(1)
> }
>
> The compiler complains about lines (1). It says
>     Formal argument of type char* const & in call to A<char*>::g(char*
>     const&) is being passed const char*.
> Uh? Why does it think the argument type is a "char* const &". I declared
> it as a "const char* &" through the template, but the compiler moved the
> placement of the const type-specifier. Why?

This is one of the reasons I recommend writing 'T const &' and 'T const *'
instead of the equivalent but confusing 'const T &' et al. Now look at

    void g(T const & t);

where T is 'char*' as in your example, then the declaration is

    void g(char * const & t);

which is a reference to a constant pointer, not a reference to pointer to
constant. What you need to do is specialize your template for pointer
types:

    template<class T> A {
    public: void g(T const & tcr);
    };

    template<class T> A<T*> {
    public: void g(T const * & tcpr);
    };

--
Bradd W. Szonye
bradds@concentric.net

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]






Author: danm@ziplink.net (Dan Muller)
Date: 1997/03/23
Raw View
In article <fjh-970323-035812@cs.mu.oz.au>,
greg_silverman@smtp.svl.trw.com says...
> I am using the Solaris 4.1 compiler. I have come across the problem of
> the const qualifier in templates having a special meaning. I shall
> illustrate:
>
> template <class T>
> class A {
>   public:
>     void g(const T& t) { }
> };
>
> int main()
> {
>   A<char*> b;
>   const char* c = new char;
>   b.g(c); //(1)
> }
>
> The compiler complains about lines (1). It says
>
> Formal argument of type char* const & in call to A<char*>::g(char* const
> &) is being passed const char*.
>
> Uh? Why does it think the argument type is a "char* const &". I declared
> it as a "const char* &" through the template, but the compiler moved the
> placement of the const type-specifier. Why?
>
Actually, this compiler behavior makes sense to me. (That's a surprise;
so many template instantiation problems seem inscrutable!)

In your example, A<T>::g(const T&) takes a reference to a const T.
A<char*> says that T is char*. So I expect that the argument to g is a
reference to a pointer which will be treated as const. The value of T
(char*) is treated as a semantic unit, not expanded in-line like a
macro.

The declaration const char*, on the other hand, declares a (non-const)
pointer to a const char. The const qualifier associates with the char,
rather than the pointer.

If your instantiation of class A<T> is really supposed to work with
const
strings, and will not be modifying them, then you should instantiate it
with A<const char*>. I tried this on with my compiler (VC++ 5.0), and it

works fine.

--
Dan Muller   danm@ziplink.net
http://www.ziplink.net/~danm

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu 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
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: "Niraj K. Patel" <nkpatel@ibm.net>
Date: 1997/03/24
Raw View
Greg Silverman wrote:
>
> I am using the Solaris 4.1 compiler. I have come across the problem of
> the const qualifier in templates having a special meaning. I shall
> illustrate:
>
> template <class T>
> class A {
>   public:
>     void g(const T& t) { }
> };
>
> int main()
> {
>   A<char*> b;
>   const char* c = new char;
>   b.g(c); //(1)
> }
>
> The compiler complains about lines (1). It says
>
> Formal argument of type char* const & in call to A<char*>::g(char* const
> &) is being passed const char*.
>
> Uh? Why does it think the argument type is a "char* const &". I declared
> it as a "const char* &" through the template, but the compiler moved the
> placement of the const type-specifier. Why?
>
{sigs snipped -clc++m mod}

Hi Greg:

I think I know what the problem is.
Templates work for an object of a built-in type or a user-defined type.
The char is a built-in type but char * is actually a pointer to
an array to us.
The template code looks at this as templates for pointers, not template
for character strings.  If indeed this is the problem then you have
two options:

1.  Use a class such as String, CString, etc. and use it in templates.
2.  Create an overloaded function for character strings that will do
what g function is doing.  Or create a class and use that in templates.

Niraj
e-mail:nkpatel@ibm.net
WWW:http://www.delanet.com/~nkpatel

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu 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
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]