Topic: Passing const obj by value into template function


Author: cliffg@my-dejanews.com
Date: 1998/08/26
Raw View
I have a question about what the standard says in regard to passing const
objects to a function taking that parameter by value (non-const). It appears
to be legal (and makes sense) for non-template functions - a copy of the
const object will be made and used within the function. But if the function
is a template function, I'm getting a syntax error (Borland C++ Builder 3.0).
I've been looking in all of the usual references, but have not found a clear
answer as to whether the syntax error is legitimate or not (according to the
standard).

If the syntax error is legitimate, it means that template function
instantiation has different rules about parameter matching, in particular for
passing objects by value. If the syntax error is not legitimate, then I can
write it off to the compiler not being mature enough.

I realize that there's different ways to code the function (particularly, for
the real-life function, a 'const T&' parameter would have been better, and
I've already told this to the original coder), but that's not the point of
this post.

Here's a minimal adaptation of the code in question:


#include <string>

class MyClass {
public:
  MyClass (const std::string& s) : str(s) { }
  MyClass () : str() { }
private:
  std::string str;
};

bool func_int (const int * some_array, int key) {
  // find key in the array
  return true; // or false, depending on whether it was found
}

bool func_MyClass (const MyClass * some_array, MyClass key) {
  // same logic as above
  return true;
}

template <class T>
bool generic_func (const T * some_array, T key) {
  // same logic as above
  return true;
}

int main () {
  int int_array[100];
  const int int_key = 5;

  bool result = func_int (int_array, int_key); // no problems compiling
  // and it makes sense - pass key in by value, making a copy of the const int

  MyClass my_array[100];
  const MyClass my_key("test value");

  result = func_MyClass (my_array, my_key); // no problems compiling
  // again makes sense - pass key in by value, making copy of const MyClass

  result = generic_func (my_array, my_key); // syntax error
  // "Could not find a match for 'generic_func(MyClass *,const MyClass)'."
  // confused - should this work or not? What does the standard say?

  return 0;
}

---

Thanks!

Cliff

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/08/27
Raw View
In article <6s1p2q$b5$1@nnrp1.dejanews.com>, cliffg@my-dejanews.com
writes
>  result = generic_func (my_array, my_key); // syntax error
>  // "Could not find a match for 'generic_func(MyClass *,const MyClass)'."
>  // confused - should this work or not? What does the standard say?
>

Have you tried explicit passing of the template arguments:

result = generic_func<MyClass>(my_array, my_key);

Your original problem is I think, related to type deduction in that it
deduces that my_key is of type MyClass const which is not the same as
the deduced type from the first parameter.

--
Francis Glassborow


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1998/08/27
Raw View
On 26 Aug 1998 20:25:00 GMT, cliffg@my-dejanews.com

>template <class T>
>bool generic_func (const T * some_array, T key) {

>  MyClass my_array[100];
>  const MyClass my_key("test value");

>  result = generic_func (my_array, my_key); // syntax error
>  // "Could not find a match for 'generic_func(MyClass *,const MyClass)'."
>  // confused - should this work or not? What does the standard say?


Your compiler is at fault.

--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: cgreen@xypoint.com
Date: 1998/08/27
Raw View
In article <wZiJqrAqjK51EwiR@robinton.demon.co.uk>,
  Francis Glassborow <francis@robinton.demon.co.uk> wrote:
> >  result = generic_func (my_array, my_key); // syntax error
> >  // "Could not find a match for 'generic_func(MyClass *,const MyClass)'."
> >  // confused - should this work or not? What does the standard say?
> >
>
> Have you tried explicit passing of the template arguments:
>
> result = generic_func<MyClass>(my_array, my_key);
>
> Your original problem is I think, related to type deduction in that it
> deduces that my_key is of type MyClass const which is not the same as
> the deduced type from the first parameter.

Thanks - I tried the template function explicit specification and it worked.
So I guess my question relates to how type deduction is supposed to work
(according to the language rules) and whether the compiler should have been
able to deduce this or not. I would have thought that the compiler could have
deduced it without needing the explicit specification (MS VC++ 5.0 did,
although I hardly use that compiler to test standards compliance ...).

Cliff

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/08/27
Raw View
In article <6s46b4$qct$1@nnrp1.dejanews.com>, cgreen@xypoint.com writes
>Thanks - I tried the template function explicit specification and it worked.
>So I guess my question relates to how type deduction is supposed to work
>(according to the language rules) and whether the compiler should have been
>able to deduce this or not. I would have thought that the compiler could have
>deduced it without needing the explicit specification (MS VC++ 5.0 did,
>although I hardly use that compiler to test standards compliance ...).


My understanding was that explicit template parameters were introduced
precisely be cause of this kind of problem.  If you only have one
template parameter put several uses as function parameters the deduced
type must be the same in all cases.  Remember that const qualification
creates a new type in C++ (you can overload on it).  The classic problem
was:

template<typename T> T & max(T &first, T &second)
        { return first>second ? first : second; }
Now you see the problem, should the return type be a const reference or
just a reference if I call it with:

int i = 3;
i += max(i, 4);

I believe that (however apparently sensible and convenient) MSVC is
wrong to make the deduction.
--
Francis Glassborow


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: AllanW@my-dejanews.com
Date: 1998/08/28
Raw View
In article <6s1p2q$b5$1@nnrp1.dejanews.com>,
  cliffg@my-dejanews.com wrote:
>
> I have a question about what the standard says in regard to passing const
> objects to a function taking that parameter by value (non-const). It appears
> to be legal (and makes sense) for non-template functions - a copy of the
> const object will be made and used within the function. But if the function
> is a template function, I'm getting a syntax error (Borland C++ Builder 3.0).
> I've been looking in all of the usual references, but have not found a clear
> answer as to whether the syntax error is legitimate or not (according to the
> standard).

The only time you can't pass by value is when the object has
a private copy constructor. That doesn't apply to the example
code below.

> If the syntax error is legitimate, it means that template function
> instantiation has different rules about parameter matching, in particular for
> passing objects by value. If the syntax error is not legitimate, then I can
> write it off to the compiler not being mature enough.

I believe it's the latter.

> I realize that there's different ways to code the function (particularly, for
> the real-life function, a 'const T&' parameter would have been better, and
> I've already told this to the original coder), but that's not the point of
> this post.

This is often better for template functions with different data
types, but not always. If the expected type is typically very
small, especially if it has math-like properties (i.e. array
indexes or dates), then passing by value may be more "natural"
and may also make the algorithm easier (eliminating the need
for a local copy by making the parameter do the copy
automatically).

> Here's a minimal adaptation of the code in question:
>
> #include <string>
>
> class MyClass {
> public:
>   MyClass (const std::string& s) : str(s) { }
>   MyClass () : str() { }
> private:
>   std::string str;
> };

Since MyClass doesn't have a copy constructor, the compiler provides
one equivalent to this:
    public: MyClass(const MyClass &o) : str(o.str) {}
Which means that you can copy a const MyClass object for various
reasons, including passing it by value.

> bool func_int (const int * some_array, int key) {
>   // find key in the array
>   return true; // or false, depending on whether it was found
> }

Good example of data best passed by value.

> bool func_MyClass (const MyClass * some_array, MyClass key) {
>   // same logic as above
>   return true;
> }

Still probably okay, depending on typical values of the key.
If it's something like a customer number, this is the way I
would do it, *especially* if I knew that class std::string
uses copy-on-write (but that's a whole other thread...)

> template <class T>
> bool generic_func (const T * some_array, T key) {
>   // same logic as above
>   return true;
> }

We don't know what type T is, so this is the most questionable
yet. But since it's meant to identify some unique element in
some_array, I say it's perfectly reasonable.

> int main () {
>   int int_array[100];
>   const int int_key = 5;
>
>   bool result = func_int (int_array, int_key); // no problems compiling
>   // and it makes sense - pass key in by value, making a copy of the const int
>
>   MyClass my_array[100];
>   const MyClass my_key("test value");
>
>   result = func_MyClass (my_array, my_key); // no problems compiling
>   // again makes sense - pass key in by value, making copy of const MyClass

For completeness, let's add:
    result = generic_func (int_array, int_key); // This should work
    // Also makes sense, for the same reasons. Does your compiler
    // choke on this?

>   result = generic_func (my_array, my_key); // syntax error
>   // "Could not find a match for 'generic_func(MyClass *,const MyClass)'."
>   // confused - should this work or not? What does the standard say?

Your compiler is confused. FWIW, Microsoft VC++5 has no problem
with this.

>   return 0;
> }

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]