Skip to content

Commit 38df936

Browse files
authored
[template] Tweak auto ref docs (#3423)
* [template] Reparent auto ref parameters section to function templates It was wrongly a child of alias templates. * Tweak wording and improve example
1 parent 2c0d274 commit 38df936

File tree

1 file changed

+60
-56
lines changed

1 file changed

+60
-56
lines changed

spec/template.dd

Lines changed: 60 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,66 @@ $(H3 $(LNAME2 return-deduction, Return Type Deduction))
13221322
---
13231323
)
13241324

1325+
$(H3 $(LNAME2 auto-ref-parameters, Auto Ref Parameters))
1326+
1327+
$(P Template functions can have auto ref parameters.
1328+
An auto ref parameter becomes a ref parameter
1329+
if its corresponding argument is an lvalue, otherwise it becomes
1330+
a value parameter:)
1331+
1332+
$(SPEC_RUNNABLE_EXAMPLE_RUN
1333+
---
1334+
int countRefs(Args...)(auto ref Args args)
1335+
{
1336+
int result;
1337+
1338+
foreach (i, _; args)
1339+
{
1340+
if (__traits(isRef, args[i]))
1341+
result++;
1342+
}
1343+
return result;
1344+
}
1345+
1346+
void main()
1347+
{
1348+
int y;
1349+
assert(countRefs(3, 4) == 0);
1350+
assert(countRefs(3, y, 4) == 1);
1351+
assert(countRefs(y, 6, y) == 2);
1352+
}
1353+
---
1354+
)
1355+
1356+
$(P Auto ref parameters can be combined with auto ref return
1357+
attributes:)
1358+
1359+
$(SPEC_RUNNABLE_EXAMPLE_RUN
1360+
---
1361+
auto ref min(T, U)(auto ref T lhs, auto ref U rhs)
1362+
{
1363+
return lhs > rhs ? rhs : lhs;
1364+
}
1365+
1366+
void main()
1367+
{
1368+
int i;
1369+
i = min(4, 3);
1370+
assert(i == 3);
1371+
1372+
int x = 7, y = 8;
1373+
i = min(x, y);
1374+
assert(i == 7);
1375+
// result is an lvalue
1376+
min(x, y) = 10; // sets x to 10
1377+
assert(x == 10 && y == 8);
1378+
1379+
static assert(!__traits(compiles, min(3, y) = 10));
1380+
static assert(!__traits(compiles, min(y, 3) = 10));
1381+
}
1382+
---
1383+
)
1384+
13251385
$(H3 $(LNAME2 function-default, Default Arguments))
13261386

13271387
$(P Template arguments not implicitly deduced can have default values:)
@@ -1409,62 +1469,6 @@ $(H2 $(LNAME2 alias-template, Alias Templates))
14091469
}
14101470
------
14111471

1412-
$(H3 $(LNAME2 auto-ref-parameters, Function Templates with Auto Ref Parameters))
1413-
1414-
$(P An auto ref function template parameter becomes a ref parameter
1415-
if its corresponding argument is an lvalue, otherwise it becomes
1416-
a value parameter:)
1417-
1418-
---
1419-
int foo(Args...)(auto ref Args args)
1420-
{
1421-
int result;
1422-
1423-
foreach (i, v; args)
1424-
{
1425-
if (v == 10)
1426-
assert(__traits(isRef, args[i]));
1427-
else
1428-
assert(!__traits(isRef, args[i]));
1429-
result += v;
1430-
}
1431-
return result;
1432-
}
1433-
1434-
void main()
1435-
{
1436-
int y = 10;
1437-
int r;
1438-
r = foo(8); // returns 8
1439-
r = foo(y); // returns 10
1440-
r = foo(3, 4, y); // returns 17
1441-
r = foo(4, 5, y); // returns 19
1442-
r = foo(y, 6, y); // returns 26
1443-
}
1444-
---
1445-
1446-
$(P Auto ref parameters can be combined with auto ref return
1447-
attributes:)
1448-
1449-
---
1450-
auto ref min(T, U)(auto ref T lhs, auto ref U rhs)
1451-
{
1452-
return lhs > rhs ? rhs : lhs;
1453-
}
1454-
1455-
void main()
1456-
{
1457-
int x = 7, y = 8;
1458-
int i;
1459-
1460-
i = min(4, 3); // returns 3
1461-
i = min(x, y); // returns 7
1462-
min(x, y) = 10; // sets x to 10
1463-
static assert(!__traits(compiles, min(3, y) = 10));
1464-
static assert(!__traits(compiles, min(y, 3) = 10));
1465-
}
1466-
---
1467-
14681472
$(H2 $(LNAME2 nested-templates, Nested Templates))
14691473

14701474
$(P If a template is declared in aggregate or function local scope, the

0 commit comments

Comments
 (0)