@@ -281,10 +281,12 @@ $(GNAME AliasAssignment):
281
281
$(GLINK_LEX Identifier) $(GLINK2 template, TemplateParameters)$(OPT) $(D =) $(GLINK StorageClasses)$(OPT) $(GLINK2 type, BasicType) $(GLINK2 function, Parameters) $(GLINK2 function, MemberFunctionAttributes)$(OPT)
282
282
)
283
283
284
- $(P $(I AliasDeclaration)s create a symbol that is an alias for another type,
285
- and can be used anywhere that other type may appear.
284
+ $(P $(I AliasDeclaration)s create a symbol name that refers to another symbol.
285
+ That symbol name can be used anywhere that the aliased symbol may appear.
286
286
)
287
287
288
+ $(H3 $(LNAME2 alias-type, Type Aliases))
289
+
288
290
--------------------
289
291
alias myint = abc.Foo.bar;
290
292
--------------------
@@ -302,6 +304,20 @@ void foo(int x) { ... }
302
304
void foo(myint m) { ... } // error, multiply defined function foo
303
305
--------------------
304
306
307
+ $(P
308
+ Type aliases can sometimes look indistinguishable from
309
+ other symbol aliases:
310
+ )
311
+
312
+ --------------------
313
+ alias abc = foo.bar; // is it a type or a symbol?
314
+ --------------------
315
+
316
+ $(BEST_PRACTICE Other than when aliasing simple basic type names,
317
+ type alias names should be Capitalized.)
318
+
319
+ $(H3 $(LNAME2 alias-symbol, Symbol Aliases))
320
+
305
321
$(P A symbol can be declared as an $(I alias) of another symbol.
306
322
For example:
307
323
)
@@ -329,16 +345,7 @@ t1.t v1; // v1 is type int
329
345
t2 v2; // v2 is type int
330
346
t3 v3; // v3 is type int
331
347
t4 v4; // v4 is type int
332
-
333
- alias Fun = int(string p);
334
- int fun(string){return 0;}
335
- static assert(is(typeof(fun) == Fun));
336
-
337
- alias MemberFun1 = int() const;
338
- alias MemberFun2 = const int();
339
- // leading attributes apply to the func, not the return type
340
- static assert(is(MemberFun1 == MemberFun2));
341
- --------------------
348
+ ---
342
349
343
350
$(P
344
351
Aliased symbols are useful as a shorthand for a long qualified
@@ -366,57 +373,44 @@ version (linux)
366
373
alias strlen = string.strlen;
367
374
--------------------
368
375
376
+ $(H3 $(LNAME2 alias-overload, Aliasing an Overload Set))
377
+
369
378
$(P
370
379
Aliases can also `import` a set of overloaded functions, that can
371
380
be overloaded with functions in the current scope:
372
381
)
373
382
383
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
374
384
--------------------
375
- class A
385
+ class B
376
386
{
377
- int foo(int a) { return 1; }
378
- }
379
-
380
- class B : A
381
- {
382
- int foo( int a, uint b ) { return 2; }
387
+ int foo(int a, uint b) { return 2; }
383
388
}
384
389
385
390
class C : B
386
391
{
387
- int foo( int a ) { return 3; }
392
+ // declaring an overload hides any base class overloads
393
+ int foo(int a) { return 3; }
394
+ // redeclare hidden overload
388
395
alias foo = B.foo;
389
396
}
390
397
391
- class D : C
392
- {
393
- }
394
-
395
- void test()
398
+ void main()
396
399
{
397
- D b = new D();
398
- int i;
400
+ import std.stdio;
399
401
400
- i = b.foo(1, 2u); // calls B.foo
401
- i = b.foo(1); // calls C.foo
402
+ C c = new C();
403
+ c.foo(1, 2u).writeln; // calls B.foo
404
+ c.foo(1).writeln; // calls C.foo
402
405
}
403
406
--------------------
407
+ )
404
408
405
- $(P
406
- $(B Note:) Type aliases can sometimes look indistinguishable from
407
- alias declarations:
408
- )
409
-
410
- --------------------
411
- alias abc = foo.bar; // is it a type or a symbol?
412
- --------------------
413
-
414
- $(P
415
- The distinction is made in the semantic analysis pass.
416
- )
409
+ $(H3 $(LNAME2 alias-variable, Aliasing Variables))
417
410
418
411
$(P Aliases cannot be used for expressions:)
419
412
413
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
420
414
-----------
421
415
struct S
422
416
{
@@ -426,10 +420,27 @@ struct S
426
420
427
421
alias a = S.i; // OK, `S.i` is a symbol
428
422
alias b = S.j; // OK. `S.j` is also a symbol
429
- alias c = a + b; // illegal, `a + b` is an expression
423
+ // alias c = a + b; // illegal, `a + b` is an expression
430
424
a = 2; // sets `S.i` to `2`
431
425
b = 4; // sets `S.j` to `4`
426
+ assert(S.i == 2);
427
+ assert(S.j == 4);
432
428
-----------
429
+ )
430
+
431
+ $(H3 $(LNAME2 alias-function, Aliasing a Function Type))
432
+
433
+ $(P Function types can be aliased:)
434
+ ---
435
+ alias Fun = int(string p);
436
+ int fun(string){return 0;}
437
+ static assert(is(typeof(fun) == Fun));
438
+
439
+ alias MemberFun1 = int() const;
440
+ alias MemberFun2 = const int();
441
+ // leading attributes apply to the func, not the return type
442
+ static assert(is(MemberFun1 == MemberFun2));
443
+ --------------------
433
444
434
445
$(P Aliases can be used to call a function with different default
435
446
arguments, change an argument from required to default or vice versa:)
@@ -467,7 +478,7 @@ void barbar(int a, int b = 6, int c = 7) {
467
478
-----------
468
479
)
469
480
470
- $(H2 $(LNAME2 AliasAssign, Alias Assign))
481
+ $(H3 $(LNAME2 AliasAssign, Alias Assign))
471
482
472
483
$(GRAMMAR
473
484
$(GNAME AliasAssign):
@@ -477,6 +488,7 @@ $(GNAME AliasAssign):
477
488
$(P An $(GLINK AliasDeclaration) can have a new value assigned to it with an
478
489
$(I AliasAssign):)
479
490
491
+ $(SPEC_RUNNABLE_EXAMPLE_COMPILE
480
492
---
481
493
template Gorgon(T)
482
494
{
@@ -486,6 +498,7 @@ template Gorgon(T)
486
498
}
487
499
pragma(msg, Gorgon!int); // prints int
488
500
---
501
+ )
489
502
490
503
$(UL
491
504
$(LI The $(I AliasAssign) and its corresponding $(I AliasDeclaration) must both be
@@ -505,9 +518,11 @@ to another $(I AliasAssign) to the same lvalue other than in the right hand side
505
518
$(I AliasAssign) is particularly useful when using an iterative
506
519
computation rather than a recursive one, as it avoids creating
507
520
the large number of intermediate templates that the recursive one
508
- engenders.
521
+ engenders.)
522
+
523
+ $(SPEC_RUNNABLE_EXAMPLE_COMPILE
509
524
---
510
- template AliasSeq(T...) { alias AliasSeq = T; }
525
+ import std.meta : AliasSeq;
511
526
512
527
static if (0) // recursive method for comparison
513
528
{
@@ -534,9 +549,9 @@ enum X = 3;
534
549
alias TK = Reverse!(int, const uint, X);
535
550
pragma(msg, TK); // prints tuple(3, (const(uint)), (int))
536
551
---
537
- )
552
+ )
538
553
539
- $(H2 $(LNAME2 alias-reassignment, Alias Reassignment))
554
+ $(H3 $(LNAME2 alias-reassignment, Alias Reassignment))
540
555
541
556
$(GRAMMAR
542
557
$(GNAME AliasReassignment):
@@ -547,15 +562,22 @@ $(GNAME AliasReassignment):
547
562
548
563
$(P An alias declaration inside a template can be reassigned a new value.)
549
564
565
+ $(SPEC_RUNNABLE_EXAMPLE_COMPILE
550
566
---
551
- template staticMap(alias F, T...)
567
+ import std.meta : AliasSeq;
568
+
569
+ template staticMap(alias F, Args...)
552
570
{
553
571
alias A = AliasSeq!();
554
- static foreach (t; T )
555
- A = AliasSeq!(A, F!T ); // alias reassignment
572
+ static foreach (Arg; Args )
573
+ A = AliasSeq!(A, F!Arg ); // alias reassignment
556
574
alias staticMap = A;
557
575
}
576
+
577
+ enum size(T) = T.sizeof;
578
+ static assert(staticMap!(size, char, wchar, dchar) == AliasSeq!(1, 2, 4));
558
579
---
580
+ )
559
581
560
582
$(P The $(I Identifier) must resolve to a lexically preceding $(GLINK AliasDeclaration).
561
583
Both must be members of the same $(GLINK2 template, TemplateDeclaration).
0 commit comments