cppannotations/yo/first/typeinference.yo
Frank B. Brokken 5a50ecd21f WIP on chapter First
git-svn-id: https://cppannotations.svn.sourceforge.net/svnroot/cppannotations/trunk@257 f6dd340e-d3f9-0310-b409-bdd246841980
2009-10-19 15:00:38 +00:00

82 lines
3.8 KiB
Text

A special use of the keyword ti(auto) is defined by the C++0x standard
allowing the compiler to determine the type of a variable automatically rather
than requiring the software engineer to define a variable's type explicitly.
In parallel, the use of tt(auto) as a storage class specifier is no longer
supported in the C++0x standard. According to that standard a variable
definition like tt(auto int var) results in a compilation error.
This can be very useful in situations where it is very hard to determine the
variable's type in advance. These situations occur, e.g., in the context of
em(templates), topics covered in chapters ref(STL) until ref(ADVANCEDTEMPL).
At this point in the Annotations only simple examples can be given, and some
hints will be provided about more general uses of the tt(auto) keyword.
When defining and initializing a variable tt(int variable = 5) the type of the
initializing expression is well known: it's an tt(int), and unless the
programmer's intentions are different this could be used to define
tt(variable)'s type (although it shouldn't in normal circumstances as it
reduces rather than improves the clarity of the code):
verb(
auto variable = 5;
)
Here are some examples where using tt(auto) em(is) useful.
In chapter ref(String) the emi(iterator) concept is introduced (see also
chapters ref(CONTAINERS) and ref(STL)). Iterators sometimes have long type
definitions, like
verb(
std::vector<std::string>::const_reverse_iterator
)
Functions may return types like this. Since the compiler knows the
types returned by functions we may exploit this knowledge using
tt(auto). Assuming that a function tt(begin()) is declared as follows:
verb(
std::vector<std::string>::const_reverse_iterator begin();
)
Rather than writing the verbose variable definition (at tt(//
1)) a much shorter definition (at tt(// 2)) may be used:
verb(
std::vector<std::string>::const_reverse_iterator iter = begin(); // 1
auto iter = begin(); // 2
)
It's easy to define additional variables of this type. When initializing
those variables using tt(iter) the tt(auto) keyword can be used again:
verb(
auto start = iter;
)
If tt(start) can't be initialized immediately using an existing
variable the type of a well known variable of function can be used in
combination with the ti(decltype) keyword, as in:
verb(
decltype(iter) start;
decltype(begin()) spare;
)
The keyword tt(decltype) may also receive an expression as its
argument. This feature is already available in the C++0x standard
implementation in g++ 4.3. E.g., tt(decltype(3 + 5)) represents an int,
tt(decltype(3 / double(3))) represents tt(double).
The tt(auto) keyword can also be used to postpone the definition of a
function's return type. The declaration of a function tt(intArrPtr) returning
a pointer to an array of 10 tt(int)s looks like this:
verb(
int (*intArrPtr())[10];
)
Such a declaration is fairly complex. E.g., among other complexities it
requires `protection of the pointer'hi(pointer protection) using parentheses
in combination with the function's parameter list. In situations like these
the specification of the return type can be postponed using the tt(auto)
return type, followed by the specification of the function's return type after
any other specification the function might receive (e.g., as a const member
(cf. section ref(ConstFunctions)) or following its exception throw list
(cf. section ref(THROWLIST))).
Using tt(auto) to declare the above function, the declaration becomes:
verb(
auto intArrPtr() -> int (*)[10];
)
A return type specification using tt(auto) is called a
emi(late-specified return type).