Стандарт C++ 98 (1119566), страница 79
Текст из файла (страница 79)
Thecomplete set of candidate functions includes all the function templates instantiated in this way and all of thenon-template overloaded functions of the same name. The function template specializations are treated likeany other functions in the remainder of overload resolution, except as explicitly noted in 13.3.3.133)2[Example:template<class T> T max(T a, T b) { return a>b?a:b; }void f(int a, int b, char c, char d){int m1 = max(a,b);// max(int a, int b)char m2 = max(c,d);// max(char a, char b)int m3 = max(a,c);// error: cannot generate max(int,char)}3Adding the non-template functionint max(int,int);to the example above would resolve the third call, by providing a function that could be called formax(a,c) after using the standard conversion of char to int for c.4Here is an example involving conversions on a function argument involved in template-argument deduction:template<class T> struct B { /* ...
*/ };template<class T> struct D : public B<T> { /* ... */ };template<class T> void f(B<T>&);void g(B<int>& bi, D<int>& di){f(bi);f(di);}5// f(bi)// f( (B<int>&)di )Here is an example involving conversions on a function argument not involved in template-parameterdeduction:template<class T> void f(T*,int);template<class T> void f(T,char);void h(int* pi, int i, char c){f(pi,i);f(pi,c);f(i,c);f(i,i);// #1// #2// #1: f<int>(pi,i)// #2: f<int*>(pi,c)// #2: f<int>(i,c);// #2: f<int>(i,char(i))}—end example]__________________133) The parameters of function template specializations contain no template parameter types.
The set of conversions allowed ondeduced arguments is limited, because the argument deduction process produces function templates with parameters that either matchthe call arguments exactly or differ only in ways that can be bridged by the allowed limited conversions. Non-deduced argumentsallow the full range of conversions.
Note also that 13.3.3 specifies that a non-template function will be given preference over a template specialization if the two functions are otherwise equally good candidates for an overload match.2896ISO/IEC 14882:1998(E)© ISO/IEC14.8.3 Overload resolution14 TemplatesOnly the signature of a function template specialization is needed to enter the specialization in a set of candidate functions. Therefore only the function template declaration is needed to resolve a call for which atemplate specialization is a candidate. [Example:template<class T> void f(T);void g(){f("Annemarie");}// declaration// call of f<const char*>The call of f is well-formed even if the template f is only declared and not defined at the point of the call.The program will be ill-formed unless a specialization for f<const char*>, either implicitly or explicitly generated, is present in some translation unit.
]290© ISO/IECISO/IEC 14882:1998(E)15 Exception handling1[except]Exception handling provides a way of transferring control and information from a point in the execution ofa program to an exception handler associated with a point previously passed by the execution. A handlerwill be invoked only by a throw-expression invoked in code executed in the handler’s try block or in functions called from the handler’s try block .try-block:try compound-statement handler-seqfunction-try-block:try ctor-initializeropt function-body handler-seqhandler-seq:handler handler-seqopthandler:catch ( exception-declaration ) compound-statementexception-declaration:type-specifier-seq declaratortype-specifier-seq abstract-declaratortype-specifier-seq...throw-expression:throw assignment-expressionoptA try-block is a statement (clause 6).
A throw-expression is of type void. Code that executes a throwexpression is said to “throw an exception;” code that subsequently gets control is called a “handler.” [Note:within this clause “try block” is taken to mean both try-block and function-try-block. ]2A goto, break, return, or continue statement can be used to transfer control out of a try block orhandler, but not into one. When this happens, each variable declared in the try block will be destroyed inthe context that directly contains its declaration.
[Example:lab:try {T1 t1;try {T2 t2;if (condition)goto lab;} catch(...) { /* handler 2 */ }} catch(...) { /* handler 1 */ }Here, executing goto lab; will destroy first t2, then t1, assuming the condition does not declare avariable. Any exception raised while destroying t2 will result in executing handler 2; any exception raisedwhile destroying t1 will result in executing handler 1.
]3A function-try-block associates a handler-seq with the ctor-initializer, if present, and the function-body. Anexception thrown during the execution of the initializer expressions in the ctor-initializer or during the execution of the function-body transfers control to a handler in a function-try-block in the same way as anexception thrown during the execution of a try-block transfers control to other handlers. [Example:291ISO/IEC 14882:1998(E)15 Exception handling© ISO/IEC15 Exception handlingint f(int);class C {int i;double d;public:C(int, double);};C::C(int ii, double id)try: i(f(ii)), d(id){// constructor function body}catch (...){// handles exceptions thrown from the ctor-initializer// and from the constructor function body}—end example]15.1 Throwing an exception1[except.throw]Throwing an exception transfers control to a handler. An object is passed and the type of that object determines which handlers can catch it. [Example:throw "Help!";can be caught by a handler of const char* type:try {// ...}catch(const char* p) {// handle character string exceptions here}andclass Overflow {// ...public:Overflow(char,double,double);};void f(double x){// ...throw Overflow(’+’,x,3.45e107);}can be caught by a handler for exceptions of type Overflowtry {// ...f(1.2);// ...}catch(Overflow& oo) {// handle exceptions of type Overflow here}—end example]292© ISO/IECISO/IEC 14882:1998(E)15 Exception handling15.1 Throwing an exception2When an exception is thrown, control is transferred to the nearest handler with a matching type (15.3);“nearest” means the handler for which the compound-statement, ctor-initializer, or function-body followingthe try keyword was most recently entered by the thread of control and not yet exited.3A throw-expression initializes a temporary object, the type of which is determined by removing any toplevel cv-qualifiers from the static type of the operand of throw and adjusting the type from “array of T” or“function returning T” to “pointer to T” or “pointer to function returning T”, respectively.
[Note: the temporary object created for a throw-expression that is a string literal is never of type char* or wchar_t*;that is, the special conversions for string literals from the types “array of const char” and “array ofconst wchar_t” to the types “pointer to char” and “pointer to wchar_t”, respectively (4.2), are neverapplied to a throw-expression. ] The temporary is used to initialize the variable named in the matchinghandler (15.3). The type of the throw-expression shall not be an incomplete type, or a pointer or referenceto an incomplete type, other than void*, const void*, volatile void*, or const volatilevoid*. Except for these restrictions and the restrictions on type matching mentioned in 15.3, the operandof throw is treated exactly as a function argument in a call (5.2.2) or the operand of a return statement.4The memory for the temporary copy of the exception being thrown is allocated in an unspecified way,except as noted in 3.7.3.1.
The temporary persists as long as there is a handler being executed for thatexception. In particular, if a handler exits by executing a throw; statement, that passes control to anotherhandler for the same exception, so the temporary remains. When the last handler being executed for theexception exits by any means other than throw; the temporary object is destroyed and the implementationmay deallocate the memory for the temporary object; any such deallocation is done in an unspecified way.The destruction occurs immediately after the destruction of the object declared in the exception-declarationin the handler.5If the use of the temporary object can be eliminated without changing the meaning of the program exceptfor the execution of constructors and destructors associated with the use of the temporary object (12.2), thenthe exception in the handler can be initialized directly with the argument of the throw expression.
Whenthe thrown object is a class object, and the copy constructor used to initialize the temporary copy is notaccessible, the program is ill-formed (even when the temporary object could otherwise be eliminated).Similarly, if the destructor for that object is not accessible, the program is ill-formed (even when the temporary object could otherwise be eliminated).6A throw-expression with no operand rethrows the exception being handled. The exception is reactivatedwith the existing temporary; no new temporary exception object is created.
The exception is no longer considered to be caught; therefore, the value of uncaught_exception() will again be true. [Example:code that must be executed because of an exception yet cannot completely handle the exception can be written like this:try {// ...}catch (...) {// catch all exceptions// respond (partially) to exceptionthrow;// pass the exception to some// other handler}—end example]7The exception thrown is the one most recently caught and not finished.
An exception is considered caughtwhen initialization is complete for the formal parameter of the corresponding catch clause, or whenterminate() or unexpected() is entered due to a throw. An exception is considered finished whenthe corresponding catch clause exits or when unexpected() exits after being entered due to a throw.8If no exception is presently being handled, executing a throw-expression with no operand callsterminate() (15.5.1).293ISO/IEC 14882:1998(E)15.2 Constructors and destructors© ISO/IEC15 Exception handling15.2 Constructors and destructors[except.ctor]1As control passes from a throw-expression to a handler, destructors are invoked for all automatic objectsconstructed since the try block was entered.