Article View: pl.comp.lang.funkcyjne
Article #767Re: j. funkcyjne - jakie zastosowania?
From: Marcin 'Qrczak' Kowalczyk
Date: Wed, 04 Jan 2006 15:42
Date: Wed, 04 Jan 2006 15:42
196 lines
9494 bytes
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-mailReferences:
<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