Topic: void as function's sole argument in template


Author: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/04/22
Raw View
sbnaran@localhost.localdomain (Siemel Naran) writes:

| On 15 Apr 99 13:38:17 GMT, Gabriel Dos_Reis <gdosreis@korrigan.inria.fr> wrote:
| >bill@gibbons.org (Bill Gibbons) writes:
|
| >| Also, the standard committee explicitly considered a proposed extension
| >| to the language to allow f(T) to describe a parameterless function when
| >| T is a template parameter "void", and rejected the proposal.
| >
| >What were the cons?
|
| To a casual reader the declaration
|    template <class T> void F(T);
| says "F is a template function taking one argument".
|
| So a call
|    int main() { F(); }
| is likely to be confusing to readers.

Do you find:

 int Min(char a, int b) { return a < b ? a : b; }

 template<typename T> T Min(T a, T b) { return T(); }

 int main() { Min('a'+'z', 255); }

less confusing?

Anyway, I had in mind situation where T=void is a explicilty given as
argument like:

 template<typename T> struct X { T f(T); };

 X<void> a;
 a.f();

or even

 template<typename T> T f(T);

 f<void>();

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr


[ 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: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/04/22
Raw View
Gabriel Dos_Reis wrote:

>         template<typename T> T f(T);
>
>         f<void>();

But it's completly pointless.

What I had in mind was to make void a regular type, with
exactly one value:

    void x = void ();
    void f ()
    { return void (); }

as unit in ML.

But it breaks when it comes to argument lists:

    void f (void);

could mean either void f () or void f (void x),
and pointers:

void v;
void* p = &v; // ok
int i;
p = &i; // illegal, i doesn't have type void

So you have to introduce another type, say Void:

    struct Void {};

such that

    Void f() { return; }

is well-defined, by a special language rule.

--

Valentin Bonnard
---
[ 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: 1999/04/19
Raw View
In C and C++ there is an incomplete type 'void' it can only be used
where incomplete types are allowed.  If you carefully study the language
you will find that this means virtually never.  In addition certain
special allowance is made wrt return types where a void return is
allowed as long as no attempt is made to capture its value.  Hence it
made sense to allow the return of an evaluation of a function whose
return type was void in a function whose return type was void.

Quite separately C overloaded the meaning of the void keyword to
disambiguate functions having no parameters from those having an
unspecified number of parameters.  C++ has no need for this except to
support legacy code.  Note that the use of void as the parameter list is
not using a type.  For this reason it is abundantly clear to me (as it
was to my fellow J16 & WG21 committee members) that:

template <typename T> T f(T);

cannot be instantiated with void, the return type is fine but the
parameter type is not, a type used in that position would have to be a
complete(d) type before any such function was called.

Please do not confuse the different meanings of keywords, doing so
ineveitably leads to confusion.


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/04/15
Raw View
clamage@eng.sun.com (Steve Clamage) writes:

[...]

| >The whole thing is to know when exactly the paramter list is determined
| >in a function declaration like T f(T). After processing the
| >parameter-declaration-clause, I guess. If so, then during intanciation
| >with T = void, we end up with a paramter list "(void)", wich should be
| >equivalent to the empty list.
|
| No, because a temlpate is NOT macro-replacement. You wind up not
| with the text string "(void)", which is a special case meaning "no
| parameters", but with a parameter type of void, which is not allowed.

OK. That is clear now.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ 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: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/04/15
Raw View
bill@gibbons.org (Bill Gibbons) writes:

[...]

| Also, the standard committee explicitly considered a proposed extension
| to the language to allow f(T) to describe a parameterless function when
| T is a template parameter "void", and rejected the proposal.

What were the cons?

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ 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: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/04/16
Raw View
Bill Gibbons <bill@gibbons.org> wrote in message
news:bill-1404991028230001@bgibbons.vip.best.com...
> Also, the standard committee explicitly considered a proposed extension
> to the language to allow f(T) to describe a parameterless function when
> T is a template parameter "void", and rejected the proposal.

Interesting.
Could someone dwell on this a bit?
I noticed that allowing trailing void parameters to functions to be ignored
would be very nice for simulating variable-arguments templates. That is:

template <class A = void, class B = void, class C = void>
struct X
{
    void f(A, B, C);
};

would instantiate a struct with a method that takes zero to three args,
depending on the types passed.

Andrei
---
[ 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: 1999/04/16
Raw View
On 15 Apr 99 08:44:36 GMT, Gabriel Dos_Reis <gdosreis@korrigan.inria.fr> wrote:
>sbnaran@localhost.localdomain (Siemel Naran) writes:

>| >>template <typename T> struct A { T f(T); };

>| ...  If T were empty, how would you call it?
>
>As I would, if given
>
> struct X { void f(void); };
>
>namely a.f(), if I intrepret 8.3.5/2 correctly:

This strikes me as contradictory.

In a previous post I wrote:
   template <class T> void f(T);
   int main() { f(); } // compile-error or call f<void>(void)
You told me that this will not call f<void>(void).  Instead,
the result is a compile time error: "there is no function
'f' of one-arg to call".  I think the error is sound.

But given
   template <class T> struct A { T f(T); };
   int main() { A<void> a; a.f(); } // compile-error or call A<void>::f(void)
If the code in the above paragraph is ill-formed, then the
code in this paragraph should be ill-formed too.


>---
> The parameter-declaration-clause determines the arguments that
> can be specified, and their processing, with the function is
> called ...
>---

--
----------------------------------
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: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1999/04/16
Raw View
On 15 Apr 99 13:38:17 GMT, Gabriel Dos_Reis <gdosreis@korrigan.inria.fr> wrote:
>bill@gibbons.org (Bill Gibbons) writes:

>| Also, the standard committee explicitly considered a proposed extension
>| to the language to allow f(T) to describe a parameterless function when
>| T is a template parameter "void", and rejected the proposal.
>
>What were the cons?

To a casual reader the declaration
   template <class T> void F(T);
says "F is a template function taking one argument".

So a call
   int main() { F(); }
is likely to be confusing to readers.

--
----------------------------------
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: James.Kanze@dresdner-bank.com
Date: 1999/04/13
Raw View
In article <xajn20fy90c.fsf@korrigan.inria.fr>,
  Gabriel Dos_Reis <gdosreis@korrigan.inria.fr> wrote:
> "Andrei Alexandrescu" <andrewalex@hotmail.com> writes:
>
> | Hello,
> |
> | I have this:
> |
> | template <typename T>
> | struct A
> | {
> |     T f(T);
> | };
> |
> | Is it allowed to instantiate it with T = void?
>
> Why not?
>
> | ... I would expect
> | A<void>::f to take no parameters and to return void.
> | CodeWarrior accepts the code, I want to be sure though.
>
> In C++,
>
>  T f() <==> T f(void)

But in C++ (and in C, if I recall correctly), X f(T) is not the same as
X f() for any given type T, including void.

It is a subtle point, but in the declaration X f(void), the void is
*not* the name of a type.  And template instantiation is *not* just
macro substitution, in which the compiler sees replacement text; the
compiler "sees" T f(T), where T is the type void.  Which is not legal.

Note that even in C (again, if I recall correctly, and I'm pretty sure
this time that I do), the following is illegal:

    typedef void T ;
    T f( T ) ;

The only thing other than empty () that is legal when declaring a
function without parameters is the literal keyword void, which in this
case is *not* the name of a type, but just a special keyword.  Any other
symbol, even one that is a type name specifying the void type, doesn't
work.  (Of course, we are talking about the output of the preprocessor
here.  #define'ing something to void does work.)

--
James Kanze                         mailto: James.Kanze@dresdner-bank.com
Conseils en informatique orient   e objet/
                        Beratung in objekt orientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany  Tel. +49 (069) 63 19 86 27

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ 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: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/04/15
Raw View
sbnaran@localhost.localdomain (Siemel Naran) writes:

| On 13 Apr 99 05:28:06 GMT, Gabriel Dos_Reis <gdosreis@korrigan.inria.fr> wrote:
|
| >No, because in
| >
| >    template <class T> T f(T t) { return t; }
| >
| >you're making the assumption that the set of values of T isn't empty.
| >That assumption doesn't hold for void.
|
| So now re-consider Andrei's code:
|
| >>template <typename T> struct A { T f(T); };
|
| The assumption here is that for the function A<T>::f(), the set of
| values of T is not empty.

hmm... I don't see anywhere that assumption is made. As far as I can
tell A<T>::f is declared to be a function of (T) returning a T. At
instantiation time with T=void, the parameter list (T) becomes (void)
which is equivalent to ().

| ...  If T were empty, how would you call it?

As I would, if given

 struct X { void f(void); };

namely a.f(), if I intrepret 8.3.5/2 correctly:

---
 The parameter-declaration-clause determines the arguments that
 can be specified, and their processing, with the function is
 called ...
---


| So do you still think that Andrei's code is correct?

Yes.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ 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: clamage@eng.sun.com (Steve Clamage)
Date: 1999/04/15
Raw View
Gabriel Dos_Reis <gdosreis@korrigan.inria.fr> writes:

>James.Kanze@dresdner-bank.com writes:

>| But in C++ (and in C, if I recall correctly), X f(T) is not the same as
>| X f() for any given type T, including void.
>|
>| It is a subtle point, but in the declaration X f(void), the void is
>| *not* the name of a type.  And template instantiation is *not* just
>| macro substitution, in which the compiler sees replacement text; the
>| compiler "sees" T f(T), where T is the type void.  Which is not legal.

Correct.

>Thanks, I'm well aware of the fact that template instanciation is not
>macro substitution.

>The whole thing is to know when exactly the paramter list is determined
>in a function declaration like T f(T). After processing the
>parameter-declaration-clause, I guess. If so, then during intanciation
>with T = void, we end up with a paramter list "(void)", wich should be
>equivalent to the empty list.

No, because a temlpate is NOT macro-replacement. You wind up not
with the text string "(void)", which is a special case meaning "no
parameters", but with a parameter type of void, which is not allowed.

--
Steve Clamage, stephen.clamage@sun.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: bill@gibbons.org (Bill Gibbons)
Date: 1999/04/15
Raw View
In article <xajg164zcqp.fsf@korrigan.inria.fr>, Gabriel Dos_Reis
<gdosreis@korrigan.inria.fr> wrote:
>
> The whole thing is to know when exactly the paramter list is determined
> in a function declaration like T f(T). After processing the
> parameter-declaration-clause, I guess. If so, then during intanciation
> with T = void, we end up with a paramter list "(void)", wich should be
> equivalent to the empty list.

The obvious counterexample is:

    typedef void T;
    int f(T);   // ill-formed



Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1999/04/13
Raw View
On 13 Apr 99 05:28:06 GMT, Gabriel Dos_Reis <gdosreis@korrigan.inria.fr> wrote:

>No, because in
>
>    template <class T> T f(T t) { return t; }
>
>you're making the assumption that the set of values of T isn't empty.
>That assumption doesn't hold for void.

So now re-consider Andrei's code:

>>template <typename T> struct A { T f(T); };

The assumption here is that for the function A<T>::f(), the set of
values of T is not empty.  If T were empty, how would you call it?
So do you still think that Andrei's code is correct?

Of course, instanting A<T> on void is ok:
   template <typename T> struct A { };
   int main() { A<void>(); } // ok

--
----------------------------------
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: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/04/13
Raw View
James.Kanze@dresdner-bank.com writes:

[...]

| But in C++ (and in C, if I recall correctly), X f(T) is not the same as
| X f() for any given type T, including void.
|
| It is a subtle point, but in the declaration X f(void), the void is
| *not* the name of a type.  And template instantiation is *not* just
| macro substitution, in which the compiler sees replacement text; the
| compiler "sees" T f(T), where T is the type void.  Which is not legal.
|
| Note that even in C (again, if I recall correctly, and I'm pretty sure
| this time that I do), the following is illegal:
|
|     typedef void T ;
|     T f( T ) ;
|
| The only thing other than empty () that is legal when declaring a
| function without parameters is the literal keyword void, which in this
| case is *not* the name of a type, but just a special keyword.  Any other
| symbol, even one that is a type name specifying the void type, doesn't
| work.  (Of course, we are talking about the output of the preprocessor
| here.  #define'ing something to void does work.)

Thanks, I'm well aware of the fact that template instanciation is not
macro substitution.

The whole thing is to know when exactly the paramter list is determined
in a function declaration like T f(T). After processing the
parameter-declaration-clause, I guess. If so, then during intanciation
with T = void, we end up with a paramter list "(void)", wich should be
equivalent to the empty list.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ 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: 1999/04/11
Raw View
On 10 Apr 99 13:40:51 GMT, Andrei Alexandrescu <andrewalex@hotmail.com> wrote:

>template <typename T>
>struct A
>{
>    T f(T); // LINE 4
>};

int main()
{
   A<void> a;
   a.f(); // LINE 10
}


[sbnaran@localhost] [/usr/local/tmp] >> como e.cc
Comeau C/C++ 4.2.38 (Oct 13 1998 03:37:37)
Copyright 1988-1998 Comeau Computing, Edison Design Group, Inc.

"e.cc", line 4: error: a parameter may not have void type
         T f(T a) { }
             ^
          detected during instantiation of class "A<T> [with T=void]" at line 9

"e.cc", line 10: error: too few arguments in function call
     a.f();
         ^


[sbnaran@localhost] [/usr/local/tmp] >> g++ --pedantic e.cc
e.cc: In function `int main()':
e.cc:10: no matching function for call to `A<void>::f ()'
e.cc:4: candidates are: A<void>::f<void>(void)



>Is it allowed to instantiate it with T = void? I would expect
>A<void>::f to take no parameters and to return void.
>CodeWarrior accepts the code, I want to be sure though.

Well, como and egcs don't accept the code.  But I don't know if
they are right or not.

--
----------------------------------
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: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/04/11
Raw View
"Andrei Alexandrescu" <andrewalex@hotmail.com> writes:

| Hello,
|
| I have this:
|
| template <typename T>
| struct A
| {
|     T f(T);
| };
|
| Is it allowed to instantiate it with T = void?

Why not?

| ... I would expect
| A<void>::f to take no parameters and to return void.
| CodeWarrior accepts the code, I want to be sure though.

In C++,

 T f() <==> T f(void)

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ 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: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/04/11
Raw View
sbnaran@localhost.localdomain (Siemel Naran) writes:

| On 10 Apr 99 13:40:51 GMT, Andrei Alexandrescu <andrewalex@hotmail.com> wrote:
|
| >template <typename T>
| >struct A
| >{
| >    T f(T); // LINE 4
| >};
|
| int main()
| {
|    A<void> a;
|    a.f(); // LINE 10
| }
|
|
| [sbnaran@localhost] [/usr/local/tmp] >> como e.cc
| Comeau C/C++ 4.2.38 (Oct 13 1998 03:37:37)
| Copyright 1988-1998 Comeau Computing, Edison Design Group, Inc.
|
| "e.cc", line 4: error: a parameter may not have void type
|          T f(T a) { }
|              ^

[...]



I don't think the program  should be rejected; 8.3.5/2 says:

---
 ... The parameter list (void) is equivalent to the empty
 parameter list. Except for this special case, void shall not
 be a parameter type.
---

What that means is:

  int f(void);  // OK #1
  int f();  // same as above
  int f(void a);  // ERROR
  int f(int, void); // ERROR


| [sbnaran@localhost] [/usr/local/tmp] >> g++ --pedantic e.cc
| e.cc: In function `int main()':
| e.cc:10: no matching function for call to `A<void>::f ()'
| e.cc:4: candidates are: A<void>::f<void>(void)

EGCS gets it wrong according to 8.3.5/2.


| >Is it allowed to instantiate it with T = void? I would expect
| >A<void>::f to take no parameters and to return void.
| >CodeWarrior accepts the code, I want to be sure though.
|
| Well, como and egcs don't accept the code.  But I don't know if
| they are right or not.

I'm curious to know how many compilers get it right.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ 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: Biju Thomas <b_thomas@ibm.net>
Date: 1999/04/12
Raw View
Gabriel Dos_Reis wrote:
>
> | On 10 Apr 99 13:40:51 GMT, Andrei Alexandrescu <andrewalex@hotmail.com> wrote:
> |
> | >template <typename T>
> | >struct A
> | >{
> | >    T f(T); // LINE 4
> | >};
> |
>
> I'm curious to know how many compilers get it right.
>

I checked this construct on VisualAge 4.0 C++ compiler, and, it accepts
the code. I hope there will be other compilers also which were released
recently.

Best regards,
Biju Thomas
---
[ 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@bardeen.ceg.uiuc.edu (Siemel Naran)
Date: 1999/04/12
Raw View
On 11 Apr 99 23:31:35 GMT, Gabriel Dos_Reis <gdosreis@korrigan.inria.fr> wrote:
>| Andrei

>| >template <typename T>
>| >struct A
>| >{
>| >    T f(T); // LINE 4
>| >};



>I don't think the program  should be rejected; 8.3.5/2 says:
>
>---
> ... The parameter list (void) is equivalent to the empty
> parameter list. Except for this special case, void shall not
> be a parameter type.
>---
>
>What that means is:
>
>  int f(void);  // OK #1
>  int f();  // same as above
>  int f(void a);  // ERROR
>  int f(int, void); // ERROR

By your reasoning, why is
   int f(void a); // ERROR
an ERROR?

It appears that these two are equivalent declarations:
   template <class T> int f(T);
   template <class T> int f(T a);
So with T==void, the two declarations should be equivalent:
   int f(void); // ok
   int f(void a); // ok

As an aside, let's go one step further.  Consider:
   template <class T> T f() { return T(); }
So a call "f<int>()" should return 0.  But how about a call
   int main() { f<void>(); }
Should this compile?

I think this should compile because
   void f<void>() { return void(); } // VERSION 1
is equivalent to
   void g() { return; } // VERSION 2
   void f() { return g(); }
The standard explicitly allows VERSION 2 to compile.
So it seems that VERSION 1 should compile too.

Back to the question at hand.  One must ask: how do you call f(T)
for T==void.  How about this?
   template <class T> T f(T t) { return t; }
   int main() { f(); }


Author: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/04/13
Raw View
sbnaran@bardeen.ceg.uiuc.edu (Siemel Naran) writes:

| On 11 Apr 99 23:31:35 GMT, Gabriel Dos_Reis <gdosreis@korrigan.inria.fr> wrote:
| >| Andrei
|
| >| >template <typename T>
| >| >struct A
| >| >{
| >| >    T f(T); // LINE 4
| >| >};
|
|
|
| >I don't think the program  should be rejected; 8.3.5/2 says:
| >
| >---
| > ... The parameter list (void) is equivalent to the empty
| > parameter list. Except for this special case, void shall not
| > be a parameter type.
| >---
| >
| >What that means is:
| >
| >  int f(void);  // OK #1
| >  int f();  // same as above
| >  int f(void a);  // ERROR
| >  int f(int, void); // ERROR
|
| By your reasoning, why is
|    int f(void a); // ERROR
| an ERROR?

Because in a fonction prototype scope, it declares the parameter 'a'
to be of type 'void': that is explicitly forbidden.

|
| It appears that these two are equivalent declarations:
|    template <class T> int f(T);
|    template <class T> int f(T a);

That is irrelevant: you're declaring template functions; there is
nothing known about the parameter type. Especially, a construct will
become ill-formed only at instanciation time, not before.

| So with T==void, the two declarations should be equivalent:
|    int f(void); // ok
|    int f(void a); // ok

No. You're forgetting the fact that with templates, full semantic
restrictions are checked only at instanciation time. Will you argue
that given current C++ rules, the following

 struct Y : int {};

is correct because

 template<typename T> struct X : T {};

is accepted ?

(as would say Nathan, argument-by-analogy is ... :-)

|
| As an aside, let's go one step further.  Consider:
|    template <class T> T f() { return T(); }
| So a call "f<int>()" should return 0.  But how about a call
|    int main() { f<void>(); }
| Should this compile?

Yes.

|
| I think this should compile because
|    void f<void>() { return void(); } // VERSION 1
| is equivalent to
|    void g() { return; } // VERSION 2
|    void f() { return g(); }
| The standard explicitly allows VERSION 2 to compile.
| So it seems that VERSION 1 should compile too.

You don't need a such a contorsion: just consider 3.9.1/9 and 6.6.3/3.

|
| Back to the question at hand.  One must ask: how do you call f(T)
| for T==void.  How about this?
|    template <class T> T f(T t) { return t; }

If you define your template function like that then you'll get an
error if you try to instanciate it with T=void. See below.

|    int main() { f(); }
| From one point of view, T deduced to be void.

Can you elaborate on how you do deduce T?


| From another point of view, there is no function f() to call --
| the only possible f's are those taking one argument, and the
| argument of course can't be void.
|
| So the question is what 8.3.5/2 applies to.
| It clearly applies to non-template code.  Eg,

templates aren't fully checked until instanciated time.

|    int f(void); // ok
|    int f(int, void); // error
| But does it apply to template code?
|    template <class T> int f(T t); // ok
|    int main() { f<void>(void); } // ok?
| That is, can f<void>() be instantiated?

No, because in

    template <class T> T f(T t) { return t; }

you're making the assumption that the set of values of T isn't empty.
That assumption doesn't hold for void.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ 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: clamage@eng.sun.com (Steve Clamage)
Date: 1999/04/13
Raw View
sbnaran@bardeen.ceg.uiuc.edu (Siemel Naran) writes:

>On 11 Apr 99 23:31:35 GMT, Gabriel Dos_Reis <gdosreis@korrigan.inria.fr> wrote:
>>| Andrei

>>| >template <typename T>
>>| >struct A
>>| >{
>>| >    T f(T); // LINE 4
>>| >};

>>I don't think the program  should be rejected; 8.3.5/2 says:
>>
>>---
>> ... The parameter list (void) is equivalent to the empty
>> parameter list. Except for this special case, void shall not
>> be a parameter type.
>>---
>>
>>What that means is:
>>
>>  int f(void);  // OK #1
>>  int f();  // same as above
>>  int f(void a);  // ERROR
>>  int f(int, void); // ERROR

>...

>So the question is what 8.3.5/2 applies to.
>It clearly applies to non-template code.  Eg,
>   int f(void); // ok
>   int f(int, void); // error
>But does it apply to template code?
>   template <class T> int f(T t); // ok
>   int main() { f<void>(void); } // ok?
>That is, can f<void>() be instantiated?

The quoted section does not say, "a single parameter of type
void." If it did, the template code could possibly be correct.
But it does not say that. It makes a special case for a
parameter list consisting of
 ( void )
Bearing in mind that templates are not macros, the function
template when instantiated on void does not meet the restrictions
on function parameters (which cannot be void), and so is invalid.

--
Steve Clamage, stephen.clamage@sun.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Andrei Alexandrescu" <andrewalex@hotmail.com>
Date: 1999/04/10
Raw View
Hello,

I have this:

template <typename T>
struct A
{
    T f(T);
};

Is it allowed to instantiate it with T = void? I would expect
A<void>::f to take no parameters and to return void.
CodeWarrior accepts the code, I want to be sure though.

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