Topic: Proposal: non-POD initializer-lists


Author: "Victor Bazarov" <vAbazarov@dAnai.com>
Date: 28 Aug 2002 17:25:08 GMT
Raw View
"Marcelo Cantos" <marcelocantos@hotmail.com> wrote...
> [I don't know how many times this idea has been bashed about here, but
> since it's new to me I thought I'd throw it out there on the off
> chance that it actually hasn't been "done to death".]
>
> I propose to solve that annoying C++ parse (object instantiation vs
> function declaration) by allowing the use of initializer lists to
> invoke user-defined constructors.  I.e.:
>
>   class Bar { };
>   class Chow { };
>
>   class Foo
>   {
>   public:
>     Foo(Bar b, Chow c);
>   };
> [...]
>
>   // Proposed syntax
>   Foo foo = { Bar(), Chow() };

I would amend it to

    Foo foo = { (Bar(),Chow()) };

just because the { x, y } may later become useful for the array
literal and could be misconstrued if 'Foo' has one-parameter
constructor as well as a two-parameter one.

>
> This proposal has the following characteristics.
>
> 1. Compatible: No existing code breaks; no existing code changes
> meaning.  (use of initializer syntax for non-POD's is currently
> illegal)
>
> 2. Unambiguous: since initializer syntax is currently illegal, this
> code could be defined to only mean "call a constructor" for non-POD's.
>
> 3. Complete: all code that currently requires function-style
> initialization could use this syntax:
>
>   // Current
>   Foo foo( (Bar()), Chow() );
>   struct S { Foo foo, int i } s = { Foo( Bar(), Chow() ), 1 };

struct S { Foo foo; int i; } ...

>   void h( Foo );
>   h( Foo( Bar(), Chow() ) );
>   foo = Foo( Bar(), Chow() );
>
>   // Proposed
>   Foo foo = { Bar(), Chow() };
>   struct S { Foo foo, int i } s = { { Bar(), Chow() }, 1 };

struct S { Foo foo; int i; } ...

>   void h( Foo, int );
>   h( { Bar(), Chow() }, 2 );
>   foo = { Bar(), Chow() };
>
> [...]
>
> I'd be happy to put some work into this proposal (C++98 change list,
> prototype implementation, etc.), but I thought since its a kind of
> obvious suggestion its probably already been tried and shot down for
> good reasons (maybe my understanding of the current rules is
> completely wrong!).  So I'm canvassing reactions before spending any
> real effort on it.

Victor
--
Please remove capital A's from my address when replying by mail


---
[ 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: marcelocantos@hotmail.com (Marcelo Cantos)
Date: Wed, 26 Jun 2002 15:50:27 GMT
Raw View
[I don't know how many times this idea has been bashed about here, but
since it's new to me I thought I'd throw it out there on the off
chance that it actually hasn't been "done to death".]

I propose to solve that annoying C++ parse (object instantiation vs
function declaration) by allowing the use of initializer lists to
invoke user-defined constructors.  I.e.:

  class Bar { };
  class Chow { };

  class Foo
  {
  public:
    Foo(Bar b, Chow c);
  };

  // Current syntax
  Foo foo(Bar(), Chow());  // Declares function; not what we expected.
  // Some current solutions.
  Foo foo((Bar()), Chow());
  Bar b;
  Foo foo(b, Chow());

The problem with the current accepted solutions is that they are prone
to breakage through mainenance.  I consider this a serious issue with
the language and not something that we simply learn work-arounds for
and promptly forget about.

Both the above solutions look bad to the untrained eye (actually they
look pretty bad to the trained eye).  Consequently, there is a high
risk that an inexperienced programmer will remove the extra
parentheses in the first solution and fold the temporary into the
function call in the second instance.  Nothing will break; in fact,
you may not even get a warning.  It may not even fail until it gets
released.

  // Proposed syntax
  Foo foo = { Bar(), Chow() };

This proposal has the following characteristics.

1. Compatible: No existing code breaks; no existing code changes
meaning.  (use of initializer syntax for non-POD's is currently
illegal)

2. Unambiguous: since initializer syntax is currently illegal, this
code could be defined to only mean "call a constructor" for non-POD's.

3. Complete: all code that currently requires function-style
initialization could use this syntax:

  // Current
  Foo foo( (Bar()), Chow() );
  struct S { Foo foo, int i } s = { Foo( Bar(), Chow() ), 1 };
  void h( Foo );
  h( Foo( Bar(), Chow() ) );
  foo = Foo( Bar(), Chow() );

  // Proposed
  Foo foo = { Bar(), Chow() };
  struct S { Foo foo, int i } s = { { Bar(), Chow() }, 1 };
  void h( Foo, int );
  h( { Bar(), Chow() }, 2 );
  foo = { Bar(), Chow() };

4. Parsimonious: No new keywords or syntax are introduced.

5. Intuitive: This syntax is already understood to mean initialization
when applied to POD's.

6. Extendable: This idea could be generalised to POD's:

  void f(a[], struct S);
  f( { 1, 2, 3 }, { { Bar(), Chow() }, 5 } );

[There is one negative I can think of...]
7. Confusing: Maybe people would think it meant "bypass the
constructors and initialize the parts".  (I would have suggested
parenthesis syntax -- foo = (Bar(), Chow()), but that's currently
legal syntax and might not avoid confusion anyway.)


I'd be happy to put some work into this proposal (C++98 change list,
prototype implementation, etc.), but I thought since its a kind of
obvious suggestion its probably already been tried and shot down for
good reasons (maybe my understanding of the current rules is
completely wrong!).  So I'm canvassing reactions before spending any
real effort on it.


Cheers,
Marcelo Cantos

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