🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.funkcyjne
Article #767

Re: j. funkcyjne - jakie zastosowania?

#767
From: Marcin 'Qrczak' Kowalczyk
Date: Wed, 04 Jan 2006 15:42
196 lines
9494 bytes
RobertSzefler <NOSPAMrszeflerNOSPAM@murator.com.pl> writes:

>>         x * y; // co to za konstrukcja?
>
> Eee... a tu jest jakaś niejednoznaczność? To jest po prostu mnożenie x
> przez y na moje oko.

To może być też definicja zmiennej y typu wskaźnik do x.

Wiesz, do czego używa się słowa kluczowego typename?

Wiedziałbyś, że poniżej trzeba dodać w tym miejscu "template"?

          class X {
          public:
                  template<size_t> X* alloc();
          };
          void f(X* p)
          {
                  X* p1 = p->alloc<200>();
                          // ill-formed: < means less than

                  X* p2 = p->template alloc<200>();
                          // fine: < starts explicit qualification
          }

Oto moje ulubione kwiatki z gramatyki C++:

  6.8  Ambiguity resolution                                 [stmt.ambig]

1 There is an ambiguity in the grammar  involving  expression-statements
  and   declarations:  An  expression-statement  with  a  function-style
  explicit type conversion (_expr.type.conv_) as its leftmost subexpres-
  sion  can  be  indistinguishable  from  a  declaration where the first
  declarator starts with a (.  In those cases the statement is a  decla-
  ration.   [Note: To disambiguate, the whole statement might have to be
  examined to determine if it is an expression-statement or  a  declara-
  tion.   This  disambiguates  many examples.  [Example: assuming T is a
  simple-type-specifier (_dcl.type_),
          T(a)->m = 7;       // expression-statement
          T(a)++;            // expression-statement
          T(a,5)<<c;         // expression-statement
          T(*d)(int);        // declaration
          T(e)[5];           // declaration
          T(f) = { 1, 2 };   // declaration
          T(*g)(double(3));  // declaration
  In the last example above, g, which is a pointer to T, is  initialized
  to  double(3).  This is of course ill-formed for semantic reasons, but
  that does not affect the syntactic analysis.   --end example]

2 The remaining cases are declarations.  [Example:
          class T {
                  // ...
          public:
                  T();
                  T(int);
                  T(int, int);
          };
          T(a);         // declaration
          T(*b)();      // declaration
          T(c)=7;       // declaration
          T(d),e,f=3;   // declaration
          extern int h;
          T(g)(h,2);    // declaration
   --end example]  --end note]

3 The disambiguation is purely syntactic; that is, the  meaning  of  the
  names  occurring  in  such  a statement, beyond whether they are type-
  names or not, is not generally used in or changed by  the  disambigua-
  tion.  Class templates are instantiated as necessary to determine if a
  qualified name is a type-name.  Disambiguation precedes parsing, and a
  statement disambiguated as a declaration may be an ill-formed declara-
  tion.  If, during parsing, a name in a  template  parameter  is  bound
  differently  than  it would be bound during a trial parse, the program
  is ill-formed.  No diagnostic is required.  [Note: This can occur only
  when the name is declared earlier in the declaration.  ] [Example:

          struct T1 {
                  T1 operator()(int x) { return T1(x); }
                  int operator=(int x) { return x; }
                  T1(int) { }
          };
          struct T2 { T2(int){ } };
          int a, (*(*b)(T2))(int), c, d;
          void f() {
                  // dismabiguation requires this to be parsed
                  // as a declaration
                  T1(a) = 3,
                  T2(4),                  // T2 will be declared as
                  (*(*b)(T2(c)))(int(d)); // a variable of type T1
                                          // but this will not allow
                                          // the last part of the
                                          // declaration to parse
                                          // properly since it depends
                                          // on T2 being a type-name
          }
   --end example]

[...]

  8.2  Ambiguity resolution                              [dcl.ambig.res]

1 The ambiguity arising from the  similarity  between  a  function-style
  cast and a declaration mentioned in _stmt.ambig_ can also occur in the
  context of a declaration.  In that context, the choice  is  between  a
  function  declaration  with  a  redundant  set of parentheses around a
  parameter name and an object declaration with a function-style cast as
  the   initializer.    Just   as   for  the  ambiguities  mentioned  in
  _stmt.ambig_, the resolution is to consider any construct  that  could
  possibly  be a declaration a declaration.  [Note: a declaration can be
  explicitly disambiguated by a nonfunction-style cast, by a = to  indi-
  cate  initialization  or  by removing the redundant parentheses around
  the parameter name.  ] [Example:
          struct S {
              S(int);
          };
          void foo(double a)
          {
              S w(int(a));        // function declaration
              S x(int());         // function declaration
              S y((int)a);        // object declaration
              S z = int(a);       // object declaration
          }
   --end example]

2 The ambiguity arising from the  similarity  between  a  function-style
  cast  and  a  type-id  can occur in different contexts.  The ambiguity
  appears as a choice between a function-style  cast  expression  and  a
  declaration  of  a  type.   The  resolution is that any construct that
  could possibly be a type-id in its syntactic context shall be  consid-
  ered a type-id.

3 [Example:
          #include <cstddef>
          char *p;
          void *operator new(size_t, int);
          void foo()  {
                  const int x = 63;
                  new (int(*p)) int;      // new-placement expression
                  new (int(*[x]));        // new type-id
          }

4 For another example,

          template <class T>
          struct S {
          T *p;
          };
          S<int()> x;             // type-id
          S<int(1)> y;            // expression (ill-formed)

5 For another example,
          void foo()
          {
                  sizeof(int(1)); // expression
                  sizeof(int());  // type-id (ill-formed)
          }

6 For another example,
          void foo()
          {
                  (int(1));       // expression
                  (int())1;       // type-id (ill-formed)
          }
   --end example]

7 Another  ambiguity arises in a parameter-declaration-clause of a func-
  tion declaration, or in a type-id that is the operand of a  sizeof  or
  typeid  operator,  when a type-name is nested in parentheses.  In this
  case, the choice is between the declaration of  a  parameter  of  type
  pointer  to function and the declaration of a parameter with redundant
  parentheses around the declarator-id.  The resolution is  to  consider
  the  type-name as a simple-type-specifier rather than a declarator-id.
  [Example:
          class C { };
          void f(int(C)) { } // void f(int (*fp)(C c)) { }
                             // not: void f(int C);

          int g(C);

          void foo() {
                  f(1);    // error: cannot convert 1 to function ptr
                  f(g);    // OK
          }
  For another example,
          class C { };
          void h(int *(C[10]));  // void h(int *(*_fp)(C _parm[10]));
                                 // not: void h(int *C[10]);
   --end example]

Chyba tylko Perl jest trudniejszy do parsowania.

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
Technical Details
Message-ID: <87hd8k0zk6.fsf@qrnik.zagroda>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news2.icm.edu.pl!newsfeed.tpinternet.pl!atlantis.news.tpi.pl!news.tpi.pl!not-for-mail
References: <dpc61g$f0l$1@news.onet.pl> <dpdvtq$oss$1@nemesis.news.tpi.pl> <slrndrn602.61b.tomasz.zielonka@localhost.localdomain> <slrndrn661.61b.tomasz.zielonka@localhost.localdomain> <dpg8ns$52m$1@nemesis.news.tpi.pl> <slrndrnguv.6eu.tomasz.zielonka@localhost.localdomain> <dpghlc$1j3v$1@news2.ipartners.pl> <slrndrnj9i.6j9.tomasz.zielonka@localhost.localdomain> <dpgkkg$1ksh$1@news2.ipartners.pl>

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news2.icm.edu.pl!newsfeed.tpinternet.pl!atlantis.news.tpi.pl!news.tpi.pl!not-for-mail
From: Marcin 'Qrczak' Kowalczyk <qrczak@knm.org.pl>
Newsgroups: pl.comp.lang.funkcyjne
Subject: Re: j. funkcyjne - jakie zastosowania?
Date: Wed, 04 Jan 2006 16:42:49 +0100
Organization: Klub Nieszkodliwych Manjaków
Lines: 196
Message-ID: <87hd8k0zk6.fsf@qrnik.zagroda>
References: <dpc61g$f0l$1@news.onet.pl> <dpdvtq$oss$1@nemesis.news.tpi.pl> <slrndrn602.61b.tomasz.zielonka@localhost.localdomain> <slrndrn661.61b.tomasz.zielonka@localhost.localdomain> <dpg8ns$52m$1@nemesis.news.tpi.pl> <slrndrnguv.6eu.tomasz.zielonka@localhost.localdomain> <dpghlc$1j3v$1@news2.ipartners.pl> <slrndrnj9i.6j9.tomasz.zielonka@localhost.localdomain> <dpgkkg$1ksh$1@news2.ipartners.pl>
NNTP-Posting-Host: paf87.warszawa.sdi.tpnet.pl
Mime-Version: 1.0
X-Trace: atlantis.news.tpi.pl 1136389386 29307 217.96.225.87 (4 Jan 2006 15:43:06 GMT)
X-Complaints-To: usenet@tpi.pl
NNTP-Posting-Date: Wed, 4 Jan 2006 15:43:06 +0000 (UTC)
X-Face: .B/ouEO}=VFkSJWE}s0@!:diHI.Z,<Ilt`:~@*]7rnn^K_y"XV8AXf^E)x*|3yVg:$FCq0Y )iGn@Z[SOA<+p}TkAv'Lzu$w{z2?F);0Xt>`m}AqK#Vjuscq(Vf1B}H[)v\9tBN}>AdP,QSRbhO]=v 3?;I+cN/Z0HKPm_Eg99/pFrU!WfpjgQ!z":>A~qt0^4):0-UuPB(6^>j!mN$)RIb)rRhXeK:+MLPW[ RVb7Kepvby-ww6_zci7Yy_@IrWW
User-Agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.4 (gnu/linux)
Cancel-Lock: sha1:nc7YbNypjUtoBJCzmYgMFywsdGg=
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit