Passing string literal arguments for reference parameters of
function templates sometimes fails in a surprising way. Consider the following
example:
The problem is that string literals have different array types
depending on their lengths. That is, "apple" and "peach" have
type char const[6] whereas "tomato" has type char
const[7]. Only the first call is possible because the template expects both
parameters to have the same type. However, if you declare nonreference
parameters, you can substitute them with string literals of different size:
The explanation for this behavior is that during argument
deduction array-to-pointer conversion (often called decay) occurs only if the parameter does not have a
reference type. This is demonstrated by the following program:
The example passes a string literal to function templates that
declare their parameter to be a reference or nonreference respectively. Both
function templates use the typeid operator to print the type of the
instantiated parameters. The typeid operator returns an lvalue of type
std::type_info, which encapsulates a representation of the type of the
expression passed to the typeid operator. The member function
name() of std::type_info is intended to return a
human-readable text representation of the latter type. The C++ standard doesn't
actually say that name() must return something meaningful, but on good
C++ implementations, you should get a string that gives a good description of
the type of the expression passed to typeid (with some implementations
this string is mangled, but a demangler is available to turn it into human-readable
text). For example, the output might be as follows:
If you encounter a problem involving a mismatch between an
array of characters and a pointer to characters, you might have stumbled on this
somewhat surprising phenomenon. There is unfortunately no general solutions
to address this problem. Depending on the context, you can
In fact, this is the reason that you cannot create a pair of values initialized with string literals using the original C++ standard library:
This was fixed with the first technical corrigendum by replacing the reference parameters of make_pair() by nonreference parameters.
-
use nonreferences instead of references (however, this can lead to unnecessary copying)
-
overload using both reference and nonreference parameters (however, this might lead to ambiguities;)
-
overload with concrete types (such as std::string)
-
overload with array types, for example:
-
force application programmers to use explicit conversions
In this example it is best to overload max() for
strings.
This is necessary anyway because without overloading in cases where the call to
max() is valid for string literals, the operation that is performed is
a pointer comparison: a<bcompares the addresses of the two string
literals and has nothing to do with lexicographical order. This is another
reason why it is usually preferable to use a string class such as
std::string instead of C-style strings.
-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------
See Also:
-----------------------------------------------------------------
- Complete Tutorial of C++ Template's
- Standard Template Library Tutorial
- Inter Process Communication Tutorial
- Advance Programming in C & C++
-----------------------------------------------------------------
No comments:
Post a Comment