cppannotations/annotations/yo/functiontemplates/lvalue.yo

73 lines
3 KiB
Text
Raw Normal View History

There are three types of emi(lvalue transformations):
itemization(
it() bf(lvalue-to-rvalue transformations.)
quote(An i(lvalue-to-rvalue transformation) is applied when an
tt(rvalue) is required, but an tt(lvalue) is provided. This happens when a
variable is used as argument to a function specifying a em(value
parameter). For example,
verb(
template<typename Type>
Type negate(Type value)
{
return -value;
}
int main()
{
int x = 5;
x = negate(x); // lvalue (x) to rvalue (copies x)
}
)
)
it() bf(array-to-pointer transformations.)
quote(An i(array-to-pointer transformation) is applied when the name
of an array is assigned to a pointer variable. This is frequently used with
functions defining pointer parameters. Such functions frequently receive
arrays as their arguments. The array's address is then assigned to the
pointer-parameter and its type is used to deduce the corresponding template
parameter's type. For example:
verb(
template<typename Type>
Type sum(Type *tp, size_t n)
{
return accumulate(tp, tp + n, Type());
}
int main()
{
int x[10];
sum(x, 10);
}
)
In this example, the location of the array tt(x) is passed to tt(sum),
expecting a pointer to some type. Using the array-to-pointer transformation,
tt(x)'s address is considered a pointer value which is assigned to tt(tp),
deducing that tt(Type) is tt(int) in the process.
)
it() bf(function-to-pointer transformations.)
quote(This transformation is most frequently used with function
templates defining a parameter which is a pointer to a function. When calling
such a function the name of a function may be specified as its argument. The
address of the function is then assigned to the pointer-parameter, deducing
the template type parameter in the process. This is called a
i(function-to-pointer transformation). For example:
verbinclude(-a examples/lvalue.cc)
In this example, the address of the tt(sqrt) function is passed to
tt(call), expecting a pointer to a function returning a tt(Type) and expecting
a tt(Type) for its argument. Using the function-to-pointer transformation,
tt(sqrt)'s address is assigned to tt(fp), deducing that tt(Type) is tt(double)
in the process (note that tt(sqrt) is the em(address) of a function, not a
variable that is a pointer to a function, hence the lvalue
transformation).
The argument tt(2.0) could not have been specified as tt(2) as there is no
tt(int sqrt(int)) prototype. Furthermore, the function's first parameter
specifies tt(Type (*fp)(Type)), rather than tt(Type (*fp)(Type const &)) as
might have been expected from our previous discussion about how to specify the
types of function template's parameters, preferring references over values.
However, tt(fp)'s argument tt(Type) is not a function template parameter, but
a parameter of the function tt(fp) points to. Since tt(sqrt) has prototype
tt(double sqrt(double)), rather than tt(double sqrt(double const &)),
tt(call)'s parameter tt(fp) em(must) be specified as tt(Type
(*fp)(Type)). It's that strict.
)
)