Topic: Has C++ got room for a more flexible function template argument deduction


Author: nesotto@cs.auc.dk ("Thorsten Ottosen")
Date: Sat, 12 Jun 2004 18:19:37 +0000 (UTC)
Raw View
"Terje Sletteb?" <tslettebo@hotmail.com> wrote in message news:b0491891.0406110004.567d6e5e@posting.google.com...
| nesotto@cs.auc.dk ("Thorsten Ottosen") wrote in message news:<40c5b0cf$0$8990$afc38c87@news.optusnet.com.au>...

| > Who uses arrays anyway?
|
| They can be nice, if you don't need a dynamically allocated
| collection. With overloaded functions taking collections, they can
| also work seamlessly with the STL, such as with the newly accepted
| Boost Collection Traits

[snip]

As you noted in the other mail, I am the submitter of that library. Array-support is part of that
library, but I can sometimes doubt that it is a good thing since it might encourage people to
actually use arrays...which is....well...not my goal at least :-)

| (I'd rather think that such "adapter"-functions would be called
| "shims" (http://www.cuj.com/documents/s=8681/cuj0308wilson/cuj0308wilson_sb1.htm),
| rather than "traits", though, as the latter is typically used for
| compile-time constants, type properties, etc., but anyway)

I still not a 100% sure about what to call those functions. What am leaning towards
is the definition of a concept called External Range and talk of these functions as the implementation of that concept
for certain types. I should note "shims" in the reference docs though. It do appears that shims has less requirements than
concepts, ie, I don't see any complexity requirement for the involved types.

br

Thorsten


---
[ 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: nesotto@cs.auc.dk ("Thorsten Ottosen")
Date: Sat, 12 Jun 2004 18:19:43 +0000 (UTC)
Raw View
"Rob Williscroft" <rtw@freenet.co.uk> wrote in message news:Xns95056D7982AE7ukcoREMOVEfreenetrtw@130.133.1.4...
| "Thorsten Ottosen" wrote in

| >| >|  char buf[10];
| >| >|
| >| >|  std::copy( "123456789", 0, buf );

[snip]

| > I think your code is pretty fancy  :-) I would never have the guts to
| > write something like that.
|
| We have a very different interpretation's of "fancy" :).

I guess so.

| In the absence of "better examples", Some more skepticism:
|
| struct X
| {
|   X( int i ) : value( i ) {}
|   int value;
| };
|
| template < typename T >
| T f( T const &lhs, T const &rhs )
| {
|   return T( lhs.value + rhs.value );
| }
|
| int main()
| {
|   X a( 1 );
|
|   f( a, 1 ); // ???
|   f( 1, a ); // ???
| }
|
| Presumably the first call to f() succedes and the second
| produces a dignostic. So we only get half a simplification.

Yeah, I guess there is serious reason to be catious here.

br

Thorsten



---
[ 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: tslettebo@hotmail.com (Terje Sletteb?)
Date: Fri, 11 Jun 2004 16:06:30 +0000 (UTC)
Raw View
nesotto@cs.auc.dk ("Thorsten Ottosen") wrote in message news:<40c5b0cf$0$8990$afc38c87@news.optusnet.com.au>...
> "Rob Williscroft" <rtw@freenet.co.uk> wrote in message news:Xns95023575022EFukcoREMOVEfreenetrtw@130.133.1.4...
> | "Thorsten Ottosen" wrote in
> | news:40c17f35$0$8989$afc38c87@news.optusnet.com.au in comp.std.c++:
> |
> | >| template< class T, class A >
> | >| void insert( std::deque<T,A>& c, typename dont_deduce<T>::type v )
> | >| {
> | >|    c.push_back( v );
> | >| }
> | >
> | > nice. but it don't "solve" anything (if there is anything to solve).
> |
> | ???
>
> you still have to know about dont_deduce<> or the hack of using an extra template argument.
> That's the "problem".

Well, it's a way of specifying "don't deduce this parameter", and I
think it's good to explicitly specify which parameter not to deduce,
rather than having the compiler "guess" it. Explicit is good. :)

I also think this way of doing it is clear enough, not to warrant a
language addition, if that's what you suggest. If so, how should it
look?

> |And even if we gain a warning, we also lose an error:
> |
> |#include <algorithm>
> |
> |int main()
> |{
> |  char buf[10];
> |
> |  std::copy( "123456789", 0, buf );
> |}
> |
>
> Who uses arrays anyway?

They can be nice, if you don't need a dynamically allocated
collection. With overloaded functions taking collections, they can
also work seamlessly with the STL, such as with the newly accepted
Boost Collection Traits
(http://cvs.sourceforge.net/viewcvs.py/boost-sandbox/boost-sandbox/libs/collection_traits/doc/collection_traits.html):

#include <boost/collection_traits.hpp>

template<class Collection,class F>
void for_each(const Collection &c,const F &f)
{
  std::for_each(boost::begin(c),boost::end(c),f);
}

This works for standard containers, arrays, std::pair of iterators,
etc.

(I'd rather think that such "adapter"-functions would be called
"shims" (http://www.cuj.com/documents/s=8681/cuj0308wilson/cuj0308wilson_sb1.htm),
rather than "traits", though, as the latter is typically used for
compile-time constants, type properties, etc., but anyway)

Another alternative is of course to use an array-wrapper, but then
it's no longer just an array.

Regards,

Terje

---
[ 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: tslettebo@hotmail.com (Terje Sletteb?)
Date: Fri, 11 Jun 2004 16:07:04 +0000 (UTC)
Raw View
nesotto@cs.auc.dk ("Thorsten Ottosen") wrote in message news:<40c66fb9$0$1588$afc38c87@news.optusnet.com.au>...
> "llewelly" <llewelly.at@xmission.dot.com> wrote in message news:864qpl98zz.fsf@Zorthluthik.local.bar...
> | nesotto@cs.auc.dk ("Thorsten Ottosen") writes:
>
>  > Who uses arrays anyway?
> | [snip]
> |
> | Everyone? Have you ever worked on a large C++ project which *doesn't*
> |     use arrays? I haven't.
>
> No, but that is just because I have never worked on a "large" C++ project. Any project I'm
> involved in won't use them.

I'm just wondering how you ever initialise strings, for example, if
not using a character array:

std::string s(/* what goes here? */);

(By the way, in my last posting in this thread, in a reply to you, I
mentioned Boost Collection Traits, and I noticed after I had sent it
that the library is by you. :) )

Regards,

Terje

---
[ 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: rtw@freenet.co.uk (Rob Williscroft)
Date: Fri, 11 Jun 2004 16:09:06 +0000 (UTC)
Raw View
"Thorsten Ottosen" wrote in
news:40c7bdd7$0$13783$afc38c87@news.optusnet.com.au in comp.std.c++:

>| >
>| >|And even if we gain a warning, we also lose an error:
>| >|
>| >|#include <algorithm>
>| >|
>| >|int main()
>| >|{
>| >|  char buf[10];
>| >|
>| >|  std::copy( "123456789", 0, buf );
>| >|}
>| >|
>| >
>| > Who uses arrays anyway?
>| >
>|
>| The example shows a diagnostic being changed to UB.
>|
>| I used an array and std::copy to show additionally that it wasn't
>| just fancy code that would be affected (I believe negatively) by this
>| change.
>
> I think your code is pretty fancy  :-) I would never have the guts to
> write something like that.

We have a very different interpretation's of "fancy" :).

>
> If you're trying to convince me the change is a bad idea, you have to
> come up with a better example. Please note that I am skeptical myself,
> I'm just not convinced that is a bad idea.
>

Then I'm just giving you reason's to be more skeptical.

I mostly disagree with your choice of which is the special case:

You want the no-conversion case to be special:

template < typename A, typename B, typename C >
  typename enable_if< is_same_type< A, B > >::type
  copy( A, B, C );

I want the conversion case to be special:

template < typename T >
  T min( T, typename identity< T >::type );


In the absence of "better examples", Some more skepticism:

struct X
{
  X( int i ) : value( i ) {}
  int value;
};

template < typename T >
T f( T const &lhs, T const &rhs )
{
  return T( lhs.value + rhs.value );
}

int main()
{
  X a( 1 );

  f( a, 1 ); // ???
  f( 1, a ); // ???
}

Presumably the first call to f() succedes and the second
produces a dignostic. So we only get half a simplification.

Add an overload f( ... ); and its a better match than the template
(currently its the only match). Would you want this rule or do
we need to keep ellipsis function's as the call-of-last-resort ?.

You get a similer issue with ADL, put X and f() in a namespace
(say ns). Now the compiler finds ns:f(), but it isn't an exact match
should it consider other namespaces ?. Clearly with the second call
ns::f() wouldn't be a match so it would consider other namespaces.

Rob.
--
http://www.victim-prime.dsl.pipex.com/

---
[ 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: wade@stoner.com (Bill Wade)
Date: Wed, 9 Jun 2004 17:08:50 +0000 (UTC)
Raw View
nesotto@cs.auc.dk ("Thorsten Ottosen") wrote in message news:<40c66fb9$0$1588$afc38c87@news.optusnet.com.au>...

> ... Any project I'm
> involved in won't use [arrays].

In the code of the first post of this thread you seem to have used at
least one object of type "array of 4 const char."

;-)

---
[ 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: rtw@freenet.co.uk (Rob Williscroft)
Date: Wed, 9 Jun 2004 20:45:36 +0000 (UTC)
Raw View
"Thorsten Ottosen" wrote in
news:40c5b0cf$0$8990$afc38c87@news.optusnet.com.au in comp.std.c++:

> "Rob Williscroft" <rtw@freenet.co.uk> wrote in message
> news:Xns95023575022EFukcoREMOVEfreenetrtw@130.133.1.4...
>| "Thorsten Ottosen" wrote in
>| news:40c17f35$0$8989$afc38c87@news.optusnet.com.au in comp.std.c++:
>|
>| >| template< class T, class A >
>| >| void insert( std::deque<T,A>& c, typename dont_deduce<T>::type v )
>| >| {
>| >|    c.push_back( v );
>| >| }
>| >
>| > nice. but it don't "solve" anything (if there is anything to
>| > solve).
>|
>| ???
>
> you still have to know about dont_deduce<> or the hack of using an
> extra template argument. That's the "problem".

Yes but how do you get current behaviour when C++ supports your
suggested behaviour ? an extra teplate paramiter and enable_if<> /
restrict_to<> ? (assuming the coder know's about it).

Your suggestion makes some cases simpler but at the expence of making
other cases more complex.

The required expertise you've removed from one part of the language
is put back (*doubled*) elsewere.

>
>|And even if we gain a warning, we also lose an error:
>|
>|#include <algorithm>
>|
>|int main()
>|{
>|  char buf[10];
>|
>|  std::copy( "123456789", 0, buf );
>|}
>|
>
> Who uses arrays anyway?
>

The example shows a diagnostic being changed to UB.

I used an array and std::copy to show additionally that it wasn't just
fancy code that would be affected (I believe negatively) by this change.

Rob.
--
http://www.victim-prime.dsl.pipex.com/

---
[ 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: nesotto@cs.auc.dk ("Thorsten Ottosen")
Date: Thu, 10 Jun 2004 17:43:27 +0000 (UTC)
Raw View
"Rob Williscroft" <rtw@freenet.co.uk> wrote in message news:Xns9503DC50ACC72ukcoREMOVEfreenetrtw@130.133.1.4...
| "Thorsten Ottosen" wrote in

| > you still have to know about dont_deduce<> or the hack of using an
| > extra template argument. That's the "problem".
|
| Yes but how do you get current behaviour when C++ supports your
| suggested behaviour ? an extra teplate paramiter and enable_if<> /
| restrict_to<> ? (assuming the coder know's about it).
|
| Your suggestion makes some cases simpler but at the expence of making
| other cases more complex.

it could be, I'm just not convinced that we need to prohibit these conversion.

| The required expertise you've removed from one part of the language
| is put back (*doubled*) elsewere.

perhaps.

| >
| >|And even if we gain a warning, we also lose an error:
| >|
| >|#include <algorithm>
| >|
| >|int main()
| >|{
| >|  char buf[10];
| >|
| >|  std::copy( "123456789", 0, buf );
| >|}
| >|
| >
| > Who uses arrays anyway?
| >
|
| The example shows a diagnostic being changed to UB.
|
| I used an array and std::copy to show additionally that it wasn't just
| fancy code that would be affected (I believe negatively) by this change.

I think your code is pretty fancy  :-) I would never have the guts to write something like
that.

If you're trying to convince me the change is a bad idea, you have to come up with a better
example. Please note that I am skeptical myself, I'm just not convinced that is a bad idea.

br

Thorsten


---
[ 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: Michiel.Salters@logicacmg.com (Michiel Salters)
Date: Mon, 7 Jun 2004 16:46:51 +0000 (UTC)
Raw View
nesotto@cs.auc.dk ("Thorsten Ottosen") wrote in message news:<40c18062$0$1584$afc38c87@news.optusnet.com.au>...
> "Michiel Salters" <Michiel.Salters@logicacmg.com> wrote in message news:fcaee77e.0406040104.7f853120@posting.google.com...
>
> | Perhaps a better solution would be to add another keyword, "deduced"
> | such that your intention can be made clear:
> |
> | template< class T, class A >
> | void insert( deque<deduced T,A>& c, T v );
>
> but isn't it a bit overkill to have a new keyword when the same can
> be done easily within the existing language?

True, /if/ the same can be done easily. I doubt it. Adding the
keyword is probably copy-paste programming, I'm adding a extra
step to the existing deduction mechanism. I can probably produce
a normative wording in a day: Table3 keywords, and 14.8.2 TAD.
In particular, there is no change needed to 14.8.3 (Overloading)
Regards,
Michiel Salters

---
[ 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: tslettebo@hotmail.com (Terje Sletteb?)
Date: Mon, 7 Jun 2004 22:35:53 +0000 (UTC)
Raw View
dsp@bdal.de ("Daniel Kr   gler (ne Spangenberg)") wrote in message news:<40C424F1.4010505@bdal.de>...
>
> Rob Williscroft schrieb:
> >
> >template < typename T >
> >struct dont deduce
> >{
> >  typedef T type;
> >};
> >
> >template< class T, class A >
> >void insert( std::deque<T,A>& c, typename dont deduce<T>::type v )
> >{
> >   c.push back( v );
> >}
> >
> >I can't say I've ever found a use for it, but I'm sure somebody has.
> >
> I have found one! Consider the following problem: In a simplified
> scenario I wanted to apply a
> general sorting function and wrote in a first attempt:

Just to add to what Rob said: You can find this template
("dont_deduce") already in Boost, in the form of mpl::identity:

http://cvs.sourceforge.net/viewcvs.py/boost/boost/boost/mpl/identity.hpp

Regards,

Terje

---
[ 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: rtw@freenet.co.uk (Rob Williscroft)
Date: Tue, 8 Jun 2004 05:09:21 +0000 (UTC)
Raw View
"Thorsten Ottosen" wrote in
news:40c17f35$0$8989$afc38c87@news.optusnet.com.au in comp.std.c++:

>| template< class T, class A >
>| void insert( std::deque<T,A>& c, typename dont_deduce<T>::type v )
>| {
>|    c.push_back( v );
>| }
>
> nice. but it don't "solve" anything (if there is anything to solve).

???

>
>| I find the current rules where an the type *must* match makes
>| understanding what template code does easier.
>
> true, but there are some places where people forget again and again to
> do something. For example,
>
> int i;
> float f;
> float f2 = std::min( f, i );
>
> if this was treated as std::min<float>( f, i ) it would be nice.
> The probably wrong
>
> float f2 = std::min( i, f );
>
> should trigger a warning just like i = f would do.

namespace nstd
{
  template < typename T >
  struct identity
  {
    typedef T type;
  };

  template < typename T >
  inline T min( T lhs, typename identity< T >::type rhs )
  {
    return lhs < rhs ? lhs : rhs;
  }
}

int main()
{
  int i = 2;
  float f = 3.2f;
  float f2 = nstd::min( f, i );

}

cl -W3 -Za -Zc:forScope,wchar_t -nologo -GR -O2 -TP -EHs test.cpp
test.cpp
test.cpp:23: warning C4244: 'argument' : conversion from 'int' to
'nstd::identity<T>::type', possible loss of data
        with
        [
            T=float
        ]

Though to be fair neither gcc 3.4 or the online EDG compiler I
tried gave the warning (gcc did tell me about an unused variable
though, which was nice :).

typeof/decltype will provide a better solution, but I still
prefer the macro.

And even if we gain a warning, we also lose an error:

#include <algorithm>

int main()
{
  char buf[10];

  std::copy( "123456789", 0, buf );
}

test.cpp:7: error C2782: '_OutIt std::copy(_InIt,_InIt,_OutIt)' :
     template parameter '_InIt' is ambiguous
     ...\Microsoft Visual Studio .NET 2003\Vc7\include\xutility:
1038: see declaration of 'std::copy'
        could be 'int'
        or       'const char *'

>
>| I also spend far more time making my templates match fewer cases
>| than I do trying to make them match more. I.e. greedy isn't good.
>
> sometimes I think it is. The whole issue is that don't want the
> type-system to be to rigid

"ridgid" is good, its easily predictable and easier to programme
against. If having simple problems being a bit more complex to solve
will let me solve complex problems more simply then thats just fine.

> , but it should rather work implicitly in
> our favor. And in some places it can be really nice with automatic
> deduction because it is
>
> 1. easier to code

But is it easier to understand ?

> 2. produce more flexible code that is unaffected by type-changes
> elsewhere

Rob.
--
http://www.victim-prime.dsl.pipex.com/

---
[ 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: nesotto@cs.auc.dk ("Thorsten Ottosen")
Date: Tue, 8 Jun 2004 18:03:06 +0000 (UTC)
Raw View
"Rob Williscroft" <rtw@freenet.co.uk> wrote in message news:Xns95023575022EFukcoREMOVEfreenetrtw@130.133.1.4...
| "Thorsten Ottosen" wrote in
| news:40c17f35$0$8989$afc38c87@news.optusnet.com.au in comp.std.c++:
|
| >| template< class T, class A >
| >| void insert( std::deque<T,A>& c, typename dont_deduce<T>::type v )
| >| {
| >|    c.push_back( v );
| >| }
| >
| > nice. but it don't "solve" anything (if there is anything to solve).
|
| ???

you still have to know about dont_deduce<> or the hack of using an extra template argument.
That's the "problem".

|And even if we gain a warning, we also lose an error:
|
|#include <algorithm>
|
|int main()
|{
|  char buf[10];
|
|  std::copy( "123456789", 0, buf );
|}
|

Who uses arrays anyway?

| >| I also spend far more time making my templates match fewer cases
| >| than I do trying to make them match more. I.e. greedy isn't good.
| >
| > sometimes I think it is. The whole issue is that don't want the
| > type-system to be to rigid
|
| "ridgid" is good, its easily predictable and easier to programme
| against. If having simple problems being a bit more complex to solve
| will let me solve complex problems more simply then thats just fine.
|
| > , but it should rather work implicitly in
| > our favor. And in some places it can be really nice with automatic
| > deduction because it is
| >
| > 1. easier to code
|
| But is it easier to understand ?

as long as it is not harder to understand. I don't think it is.

br

Thorsten


---
[ 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: rtw@freenet.co.uk (Rob Williscroft)
Date: Wed, 9 Jun 2004 02:42:02 +0000 (UTC)
Raw View
Seungbeom Kim wrote in news:ca58ff$1iv$1@news.Stanford.EDU in comp.std.c++:

> Rob Williscroft wrote:
>>
>> And even if we gain a warning, we also lose an error:
>>
>> #include <algorithm>
>>
>> int main()
>> {
>>   char buf[10];
>>
>>   std::copy( "123456789", 0, buf );
>> }
>
> By the way, what does this program do (assuming we change the 0
> to static_cast<const char*>(0) to make it compile)?
> Is a null pointer a valid iterator input to std::copy? I doubt it.
>

My point was that it's an error, and IMO it should stay that way.

If the language rules were changed and the programme compiled it
would when run exhibt UB as it attempts to write beyond the
and of local array 'buf'.

Rob.
--
http://www.victim-prime.dsl.pipex.com/

---
[ 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: nesotto@cs.auc.dk ("Thorsten Ottosen")
Date: Wed, 9 Jun 2004 02:42:11 +0000 (UTC)
Raw View
"llewelly" <llewelly.at@xmission.dot.com> wrote in message news:864qpl98zz.fsf@Zorthluthik.local.bar...
| nesotto@cs.auc.dk ("Thorsten Ottosen") writes:

 > Who uses arrays anyway?
| [snip]
|
| Everyone? Have you ever worked on a large C++ project which *doesn't*
|     use arrays? I haven't.

No, but that is just because I have never worked on a "large" C++ project. Any project I'm
involved in won't use them.

It change nothing about the fact that arrays are not needed in C++ code and that they shouldn't be
used directly.

If one absolutely must use arrays anyway, one should use boost::array<>.

br

Thorsten


---
[ 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: Michiel.Salters@logicacmg.com (Michiel Salters)
Date: Fri, 4 Jun 2004 16:07:58 +0000 (UTC)
Raw View
nesotto@cs.auc.dk ("Thorsten Ottosen") wrote in message news:<40be87a3$0$8988$afc38c87@news.optusnet.com.au>...
> Condsider this function
>
> template< class T, class A >
> void insert( deque<T,A>& c, T v )
> {
>    c.push_back( v );
> }
>
> deque<string> ds;
> deque<float>   df;
> insert( ds, "foo" ); // error
> insert( df, 1 );       // error
>
> If we change the definition of insert to
>
> template< class T, class A, class U >
> void insert( deque<T,A>& c, U v )
> {
>    c.push_back( v );
> }
>
> insert( ds, "foo" ); // no error
> insert( df, 1 );       // no error
>
> One might say it is a little inconvenient to have to specify
> the third template argument. Can anyone deduce if it would be
> feasable to allow the original version to compile given that
> there are no other overloads of the form void insert( deque<T,A>&, U ) ?

Tricky, because your statement doesn't address where those other
overloads may be. In the usual model, I'd take it no other overloads
may exist within the same TU.

Perhaps a better solution would be to add another keyword, "deduced"
such that your intention can be made clear:

template< class T, class A >
void insert( deque<deduced T,A>& c, T v );

The meaning of this keyword would be that it occurs only within the
argument lists of function templates. Template argument deduction would
be a three-stage process:
1) Use the explicitly provided parameters
2, new) Deduce the template parameters that ocur prefixed wiht "deduced",
        ignoring any non-prefixed occurrence.
3) Deduce the non-prefixed template parameters.

In steps 2 and 3, template parameters that have been deduced before are
skipped. The resulting signature is still checked for consistency and
against the actual arguments. If there are two occurences of "deduced T",
they must still result in the same type for T.

In the example I gave, one could call the insert function like this:

deque<int> foo;
insert( foo, 2.5 );

The modified TAD process would then deduce T from the type of foo only.
In the last step, only A is deduced. The actual arguments are then checked,
and the call succeeds because 2.5 can be converted to T==int.

Regards,
Michiel Salters

---
[ 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: rtw@freenet.co.uk (Rob Williscroft)
Date: Fri, 4 Jun 2004 19:23:22 +0000 (UTC)
Raw View
"Thorsten Ottosen" wrote in
news:40be87a3$0$8988$afc38c87@news.optusnet.com.au in comp.std.c++:

> Condsider this function
>
> template< class T, class A >
> void insert( deque<T,A>& c, T v )
> {
>    c.push_back( v );
> }
>
> deque<string> ds;
> deque<float>   df;
> insert( ds, "foo" ); // error
> insert( df, 1 );       // error
>
> If we change the definition of insert to
>
> template< class T, class A, class U >
> void insert( deque<T,A>& c, U v )
> {
>    c.push_back( v );
> }
>
> insert( ds, "foo" ); // no error
> insert( df, 1 );       // no error
>

#include <deque>
#include <string>

template < typename T >
struct dont_deduce
{
  typedef T type;
};

template< class T, class A >
void insert( std::deque<T,A>& c, typename dont_deduce<T>::type v )
{
   c.push_back( v );
}

int main()
{
  std::deque< std::string > ds;
  std::deque<float>   df;
  insert( ds, "foo" );
  insert( df, 1 );
}

Once we get template typedefs this might become:

template< class T, class A >
void insert( std::deque<T,A>& c, std::identity<T> v )
{
   c.push_back( v );
}

This leaves what happens in the programmers hands:

template < typename T >
struct dont_deduce
{
  typedef T type;
};


template < typename T >
struct thing
{
  thing() {}
  thing( int ) {}
};

template< class T >
void whatever( thing< typename dont_deduce<T>::type > const& c, T v )
{
}

int main()
{
  whatever( 0, 1.2f );

  thing< int > ti;
  whatever( ti, 0 );
}

I can't say I've ever found a use for it, but I'm sure somebody has.

I find the current rules where an the type *must* match makes
understanding what template code does easier.

I also spend far more time making my templates match fewer cases
than I do trying to make them match more. I.e. greedy isn't good.

   0.02-ly yr's Rob.
--
http://www.victim-prime.dsl.pipex.com/

---
[ 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: nesotto@cs.auc.dk ("Thorsten Ottosen")
Date: Sat, 5 Jun 2004 16:54:07 +0000 (UTC)
Raw View

"Rob Williscroft" <rtw@freenet.co.uk> wrote in message news:Xns94FEC918D980ukcoREMOVEfreenetrtw@130.133.1.4...

[snip]
| > If we change the definition of insert to
| >
| > template< class T, class A, class U >
| > void insert( deque<T,A>& c, U v )
| > {
| >    c.push_back( v );
| > }
| >
| > insert( ds, "foo" ); // no error
| > insert( df, 1 );       // no error

[snip]

| template < typename T >
| struct dont_deduce
| {
|   typedef T type;
| };
|
| template< class T, class A >
| void insert( std::deque<T,A>& c, typename dont_deduce<T>::type v )
| {
|    c.push_back( v );
| }

nice. but it don't "solve" anything (if there is anything to solve).

| I find the current rules where an the type *must* match makes
| understanding what template code does easier.

true, but there are some places where people forget again and again to do something.
For example,

int i;
float f;
float f2 = std::min( f, i );

if this was treated as std::min<float>( f, i ) it would be nice.
The probably wrong

float f2 = std::min( i, f );

should trigger a warning just like i = f would do.

| I also spend far more time making my templates match fewer cases
| than I do trying to make them match more. I.e. greedy isn't good.

sometimes I think it is. The whole issue is that don't want the type-system to be to rigid, but
it should rather work implicitly in our favor. And in some places it can be really nice with
automatic deduction because it is

1. easier to code
2. produce more flexible code that is unaffected by type-changes elsewhere

br

Thorsten



---
[ 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: nesotto@cs.auc.dk ("Thorsten Ottosen")
Date: Sat, 5 Jun 2004 16:54:10 +0000 (UTC)
Raw View

"Michiel Salters" <Michiel.Salters@logicacmg.com> wrote in message news:fcaee77e.0406040104.7f853120@posting.google.com...

| Perhaps a better solution would be to add another keyword, "deduced"
| such that your intention can be made clear:
|
| template< class T, class A >
| void insert( deque<deduced T,A>& c, T v );

but isn't it a bit overkill to have a new keyword when the same can be done easily within the existing language?

br

Thorsten


---
[ 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: nesotto@cs.auc.dk ("Thorsten Ottosen")
Date: Thu, 3 Jun 2004 17:25:58 +0000 (UTC)
Raw View
Condsider this function

template< class T, class A >
void insert( deque<T,A>& c, T v )
{
   c.push_back( v );
}

deque<string> ds;
deque<float>   df;
insert( ds, "foo" ); // error
insert( df, 1 );       // error

If we change the definition of insert to

template< class T, class A, class U >
void insert( deque<T,A>& c, U v )
{
   c.push_back( v );
}

insert( ds, "foo" ); // no error
insert( df, 1 );       // no error

One might say it is a little inconvenient to have to specify the third template argument.
Can anyone deduce if it would be feasable to allow the original version to compile
given that there are no other overloads of the form void insert( deque<T,A>&, U ) ?

Thanks

Thorsten


---
[ 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: omni@scient.net ("Jaded Hobo")
Date: Fri, 4 Jun 2004 16:05:49 +0000 (UTC)
Raw View
The problem with your code snippet is that your hoping to get implicit
conversion. It compiles just fine if you
match the type of the second parameter to that of the deque.
Given your first version of insert these calls work:
insert( ds, string( "boohoo" ) );
insert( df, 1.0f );

""Thorsten Ottosen"" <nesotto@cs.auc.dk> schreef in bericht
news:40be87a3$0$8988$afc38c87@news.optusnet.com.au...
> Condsider this function
>
> template< class T, class A >
> void insert( deque<T,A>& c, T v )
> {
>    c.push_back( v );
> }
>
> deque<string> ds;
> deque<float>   df;
> insert( ds, "foo" ); // error
> insert( df, 1 );       // error
>
> If we change the definition of insert to
>
> template< class T, class A, class U >
> void insert( deque<T,A>& c, U v )
> {
>    c.push_back( v );
> }
>
> insert( ds, "foo" ); // no error
> insert( df, 1 );       // no error
>
> One might say it is a little inconvenient to have to specify the third
template argument.
> Can anyone deduce if it would be feasable to allow the original version to
compile
> given that there are no other overloads of the form void insert(
deque<T,A>&, U ) ?
>
> Thanks
>
> Thorsten
>
>
> ---
> [ 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                       ]
>


---
[ 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                       ]