Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Function declaration

      From cppreference.com
      <cpp‎ |language
       
       
      C++ language
      General topics
      Flow control
      Conditional execution statements
      Iteration statements (loops)
      Jump statements
      Functions
      Function declaration
      Lambda function expression
      inline specifier
      Dynamic exception specifications(until C++17*)
      noexcept specifier(C++11)
      Exceptions
      Namespaces
      Types
      Specifiers
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      Storage duration specifiers
      Initialization
      Expressions
      Alternative representations
      Literals
      Boolean -Integer -Floating-point
      Character -String -nullptr(C++11)
      User-defined(C++11)
      Utilities
      Attributes(C++11)
      Types
      typedef declaration
      Type alias declaration(C++11)
      Casts
      Memory allocation
      Classes
      Class-specific function properties
      Special member functions
      Templates
      Miscellaneous
       
       

      A function declaration introduces the function name and its type. A function definition associates the function name/type with the function body.

      Contents

      [edit]Function declaration

      Function declarations may appear in any scope. A function declaration at class scope introduces a class member function (unless thefriend specifier is used), seemember functions andfriend functions for details.

      noptr-declarator(parameter-list)cv (optional)ref  (optional)except (optional)attr (optional) (1)
      noptr-declarator(parameter-list)cv (optional)ref  (optional)except (optional)attr (optional)
      ->trailing
      (2)(since C++11)

      (seeDeclarations for the other forms of thedeclarator syntax)

      1) Regular function declarator syntax.
      2) Trailing return type declaration. Thedecl-specifier-seq in this case must contain the keywordauto.
      noptr-declarator - any validdeclarator, but if it begins with*,&, or&&, it has to be surrounded by parentheses.
      parameter-list - possibly empty, comma-separated list of the function parameters (see below for details)
      attr -(since C++11) a list ofattributes. These attributes are applied to the type of the function, not the function itself. The attributes for the function appear after the identifier within the declarator and are combined with the attributes that appear in the beginning of the declaration, if any.
      cv - const/volatile qualification, only allowed in non-static member function declarations
      ref -(since C++11) ref-qualification, only allowed in non-static member function declarations
      except -

      dynamic exception specification

      (until C++11)

      eitherdynamic exception specification
      ornoexcept specification

      (since C++11)
      (until C++17)

      noexcept specification

      (since C++17)
      trailing - Trailing return type, useful if the return type depends on argument names, such astemplate<class T,class U>auto add(T t, U u)-> decltype(t+ u); or is complicated, such as inauto fpif(int)->int(*)(int)


      As mentioned inDeclarations, the declarator can be followed by arequires clause, which declares the associatedconstraints for the function, which must be satisfied in order for the function to be selected byoverload resolution. (example:void f1(int a) requirestrue;) Note that the associated constraint is part of function signature, but not part of function type.

      (since C++20)

      Function declarators can be mixed with other declarators, where thedeclaration specifier sequence allows:

      // declares an int, an int*, a function, and a pointer to a functionint a=1,*p=NULL, f(),(*pf)(double);// decl-specifier-seq is int// declarator f() declares (but doesn't define)//                a function taking no arguments and returning int struct S{virtualint f(char)const, g(int)&&;// declares two non-static member functionsvirtualint f(char), x;// compile-time error: virtual (in decl-specifier-seq)// is only allowed in declarations of non-static// member functions};

      Using a volatile-qualified object type as parameter type or return type is deprecated.

      (since C++20)

      The return type of a function cannot be a function type or an array type (but can be a pointer or reference to those).

      As with any declaration, attributes that appear before the declaration and the attributes that appear immediately after the identifier within the declarator both apply to the entity being declared or defined (in this case, to the function):

      [[noreturn]]void f[[noreturn]]();// OK: both attributes apply to the function f

      However, the attributes that appear after the declarator (in the syntax above), apply to the type of the function, not to the function itself:

      void f()[[noreturn]];// Error: this attribute has no effect on the function itself
      (since C++11)

      Return type deduction

      If thedecl-specifier-seq of the function declaration contains the keywordauto, trailing return type may be omitted, and will be deduced by the compiler from the type of the operand used in thenon-discardedreturn statement. If the return type does not usedecltype(auto), the deduction follows the rules oftemplate argument deduction:

      int x=1;auto f(){return x;}// return type is intconstauto& f(){return x;}// return type is const int&

      If the return type isdecltype(auto), the return type is as what would be obtained if the operand used in the return statement were wrapped indecltype:

      int x=1;decltype(auto) f(){return x;}// return type is int, same as decltype(x)decltype(auto) f(){return(x);}// return type is int&, same as decltype((x))

      (note: “const decltype(auto)&” is an error,decltype(auto) must be used on its own)

      If there are multiple return statements, they must all deduce to the same type:

      auto f(bool val){if(val)return123;// deduces return type intelsereturn3.14f;// Error: deduces return type float}

      If there is no return statement or if the operand of the return statement is a void expression (including return statements with no operand), the declared return type must be eitherdecltype(auto), in which case the deduced return type isvoid, or (possibly cv-qualified)auto, in which case the deduced return type is then (identically cv-qualified)void:

      auto f(){}// returns voidauto g(){return f();}// returns voidauto* x(){}// Error: cannot deduce auto* from void

      Once a return statement has been seen in a function, the return type deduced from that statement can be used in the rest of the function, including in other return statements:

      auto sum(int i){if(i==1)return i;// sum’s return type is intelsereturn sum(i-1)+ i;// OK: sum’s return type is already known}

      If the return statement uses abrace-enclosed initializer list, deduction is not allowed:

      auto func(){return{1,2,3};}// Error

      Virtual functions andcoroutines(since C++20) cannot use return type deduction:

      struct F{virtualauto f(){return2;}// Error};

      Function templates other thanuser-defined conversion functions can use return type deduction. The deduction takes place at instantiation even if the expression in the return statement is notdependent. This instantiation is not in an immediate context for the purposes ofSFINAE.

      template<class T>auto f(T t){return t;}typedef decltype(f(1)) fint_t;// instantiates f<int> to deduce return type template<class T>auto f(T* t){return*t;}void g(){int(*p)(int*)=&f;}// instantiates both fs to determine return types,// chooses second template overload

      Redeclarations or specializations of functions or function templates that use return type deduction must use the same return type placeholders:

      auto f(int num){return num;}// int f(int num);            // Error: no placeholder return type// decltype(auto) f(int num); // Error: different placeholder template<typename T>auto g(T t){return t;}templateauto g(int);// OK: return type is int// template char g(char); // Error: not a specialization of the primary template g

      Similarly, redeclarations or specializations of functions or function templates that do not use return type deduction must not use a placeholder:

      int f(int num);// auto f(int num) { return num; } // Error: not a redeclaration of f template<typename T>T g(T t){return t;}templateint g(int);// OK: specialize T as int// template auto g(char); // Error: not a specialization of the primary template g

      Explicit instantiation declarations do not themselves instantiate function templates that use return type deduction:

      template<typename T>auto f(T t){return t;}externtemplateauto f(int);// does not instantiate f<int> int(*p)(int)= f;// instantiates f<int> to determine its return type,// but an explicit instantiation definition// is still required somewhere in the program
      (since C++14)

      [edit]Parameter list

      The parameter list determines the arguments that can be specified when the function is called. It is a comma-separated list ofparameter declarations, each of which has the following syntax:

      attr (optional)decl-specifier-seqdeclarator (1)

      attr (optional)thisdecl-specifier-seqdeclarator

      (2)(since C++23)
      attr (optional)decl-specifier-seqdeclarator=initializer (3)
      attr (optional)decl-specifier-seqabstract-declarator (optional) (4)

      attr (optional)thisdecl-specifier-seqabstract-declarator (optional)

      (5)(since C++23)
      attr (optional)decl-specifier-seqabstract-declarator (optional)=initializer (6)
      void (7)
      1) Declares a named (formal) parameter. For the meanings ofdecl-specifier-seq anddeclarator, seedeclarations.
      int f(int a,int* p,int(*(*x)(double))[3]);
      2) Declares a namedexplicit object parameter.
      3) Declares a named (formal) parameter with adefault value.
      int f(int a=7,int* p= nullptr,int(*(*x)(double))[3]= nullptr);
      4) Declares an unnamed parameter.
      int f(int,int*,int(*(*)(double))[3]);
      5) Declares a unnamedexplicit object parameter.
      6) Declares an unnamed parameter with adefault value.
      int f(int=7,int*= nullptr,int(*(*)(double))[3]= nullptr);
      7) Indicates that the function takes no parameters, it is the exact synonym for an empty parameter list:int f(void); andint f(); declare the same function.
      void is the only syntax equivalent to an empty parameter list, other usages ofvoid parameters are ill-formed:
      Incorrect usageExample
      multiple parameters are presentint f1(void,int);
      thevoid parameter is namedinf f2(void param);
      void is cv-qualifiedint f3(constvoid);
      void isdependentint f4(T); (whereT isvoid)
      thevoid parameter is anexplicit object parameter(since C++23)int f5(thisvoid);

      Althoughdecl-specifier-seq implies there can existspecifiers other than type specifiers, the only other specifier allowed isregister as well asauto(until C++11), and it has no effect.

      (until C++17)

      If any of the function parameters uses aplaceholder (eitherauto or aconcept type), the function declaration is instead anabbreviated function template declaration:

      void f1(auto);// same as template<class T> void f1(T)void f2(C1auto);// same as template<C1 T> void f2(T), if C1 is a concept
      (since C++20)

      A parameter declaration with the specifierthis (syntax(2)/(5)) declares anexplicit object parameter.

      An explicit object parameter cannot be afunction parameter pack, and it can only appear as the first parameter of the parameter list in the following declarations:

      A member function with an explicit object parameter has the following restrictions:

      • The function is notstatic.
      • The function is notvirtual.
      • The declarator of the function does not containcv andref.
      struct C{void f(this C& self);// OK template<typename Self>void g(this Self&& self);// also OK for templates void p(this C)const;// Error: “const” not allowed herestaticvoid q(this C);// Error: “static” not allowed herevoid r(int, this C);// Error: an explicit object parameter//        can only be the first parameter}; // void func(this C& self);   // Error: non-member functions cannot have//        an explicit object parameter
      (since C++23)

      Parameter names declared in function declarations are usually for only self-documenting purposes. They are used (but remain optional) in function definitions.

      An ambiguity arises in a parameter list when a type name is nested in parentheses (includinglambda expressions)(since C++11). In this case, the choice is between the declaration of a parameter of type pointer to function and the declaration of a parameter with redundant parentheses around the identifier of thedeclarator. The resolution is to consider the type name as asimple type specifier (which is the pointer to function type):

      class C{}; void f(int(C)){}// void f(int(*fp)(C param)) {}// NOT void f(int C) {} void g(int*(C[10]));// void g(int *(*fp)(C param[10]));// NOT void g(int *C[10]);

      Parameter type cannot be a type that includes a reference or a pointer to array of unknown bound, including a multi-level pointers/arrays of such types, or a pointer to functions whose parameters are such types.

      [edit]Using an ellipsis

      The last parameter in the parameter list can be an ellipsis (...); this declares avariadic function. The comma preceding the ellipsis can be omitted(deprecated in C++26):

      int printf(constchar* fmt, ...);// a variadic functionint printf(constchar* fmt...);// same as above, but deprecated since C++26 template<typename...Args>void f(Args..., ...);// a variadic function template with a parameter pack template<typename...Args>void f(Args... ...);// same as above, but deprecated since C++26 template<typename...Args>void f(Args......);// same as above, but deprecated since C++26

      [edit]Function type

      [edit]Parameter-type-list

      A function’sparameter-type-list is determined as follows:

      1. The type of each parameter (including functionparameter packs)(since C++11) is determined from its ownparameter declaration.
      2. After determining the type of each parameter, any parameter of type “array ofT” or of function typeT is adjusted to be “pointer toT”.
      3. After producing the list of parameter types, any top-levelcv-qualifiers modifying a parameter type are deleted when forming the function type.
      4. The resulting list of transformed parameter types and the presence or absence of theellipsis or a functionparameter pack(since C++11) is the function’s parameter-type-list.
      void f(char*);// #1void f(char[]){}// defines #1void f(constchar*){}// OK, another overloadvoid f(char*const){}// Error: redefines #1 void g(char(*)[2]);// #2void g(char[3][2]){}// defines #2void g(char[3][3]){}// OK, another overload void h(int x(constint));// #3void h(int(*)(int)){}// defines #3

      [edit]Determining function type

      In syntax(1), assumingnoptr-declarator as a standalone declaration, given the type of thequalified-id orunqualified-id innoptr-declarator as “derived-declarator-type-listT”:

      • If the exception specification isnon-throwing, the type of the function declared is
        “derived-declarator-type-listnoexcept function of
        parameter-type-listcv (optional)ref  (optional) returningT”.
      (since C++17)
      • The(until C++17)Otherwise, the(since C++17) type of the function declared is
        “derived-declarator-type-list function of
        parameter-type-listcv (optional)ref  (optional)(since C++11) returningT”.

      In syntax(2), assumingnoptr-declarator as a standalone declaration, given the type of thequalified-id orunqualified-id innoptr-declarator as “derived-declarator-type-listT” (T must beauto in this case):

      (since C++11)
      • If the exception specification isnon-throwing, the type of the function declared is
        “derived-declarator-type-listnoexcept function of
        parameter-type-listcv (optional)ref  (optional) returningtrailing ”.
      (since C++17)
      • The(until C++17)Otherwise, the(since C++17) type of the function declared is
        “derived-declarator-type-list function of
        parameter-type-listcv (optional)ref  (optional) returningtrailing ”.

      attr, if present, applies to the function type.

      (since C++11)
      // the type of “f1” is// “function of int returning void, with attribute noreturn”void f1(int a)[[noreturn]]; // the type of “f2” is// “constexpr noexcept function of pointer to int returning int”constexprauto f2(int[] b)noexcept->int; struct X{// the type of “f3” is// “function of no parameter const returning const int”constint f3()const;};

      [edit]Trailing qualifiers

      A function type withcv  orref  (since C++11) (including a type named bytypedef name) can appear only as:

      typedefint FIC(int)const;FIC f;// Error: does not declare a member function struct S{    FIC f;// OK}; FIC S::*pm=&S::f;// OK

      [edit]Function signature

      Every function has a signature.

      The signature of a function consists of its name andparameter-type-list. Its signature also contains the enclosingnamespace, with the following exceptions:

      • If the function is amember function, its signature contains the class of which the function is a member instead of the enclosing namespace. Its signature also contains the following components, if exists:
      • cv
      • ref
      (since C++11)
      • trailingrequires clause
      • If the function is a non-templatefriend function with a trailingrequires clause, its signature contains the enclosing class instead of the enclosing namespace. The signature also contains the trailingrequires clause.
      (since C++20)

      except andattr(since C++11) doesn't involve function signature, althoughnoexcept specification affects the function type(since C++17).

      [edit]Function definition

      A non-member function definition may appear at namespace scope only (there are no nested functions). Amember function definition may also appear in the body of aclass definition. They have the following syntax:

      attr (optional)decl-specifier-seq (optional)declarator
      virt-specs (optional)contract-specs (optional)function-body
      (1)
      attr (optional)decl-specifier-seq (optional)declarator
      requires-clausecontract-specs (optional)function-body
      (2)(since C++20)
      1) A function definition without constraints.
      2) A function definition with constraints.
      attr -(since C++11) a list ofattributes. These attributes are combined with the attributes after the identifier in thedeclarator (see top of this page), if any.
      decl-specifier-seq - the return type with specifiers, as in thedeclaration grammar
      declarator - function declarator, same as in the function declaration grammar above (can be parenthesized)
      virt-specs -(since C++11)override,final, or their combination in any order
      requires-clause - arequires clause
      contract-specs -(since C++26) a list offunction contract specifiers
      function-body - the function body (see below)


      function-body is one of the following:

      ctor-initializer (optional)compound-statement (1)
      function-try-block (2)
      =default; (3)(since C++11)
      =delete; (4)(since C++11)
      =delete(string-literal); (5)(since C++26)
      1) Regular function body.
      2)Functiontry block.
      3) Explicitly defaulted function definition.
      4) Explicitly deleted function definition.
      5) Explicitly deleted function definition with error message.
      ctor-initializer -member initializer list, only allowed in constructors
      compound-statement - the brace-enclosedsequence of statements that constitutes the body of a function
      function-try-block - afunctiontry block
      string-literal - anunevaluated string literal that could be used to explain the rationale for why the function is deleted
      int max(int a,int b,int c){int m=(a> b)? a: b;return(m> c)? m: c;} // decl-specifier-seq is “int”// declarator is “max(int a, int b, int c)”// body is { ... }

      The function body is acompound statement (sequence of zero or more statements surrounded by a pair of curly braces), which is executed when the function call is made. Moreover, the function body of aconstructor also includes the following:

      If a function definition contains avirt-specs, it must define amember function.

      (since C++11)

      If a function definition contains arequires-clause, it must define atemplated function.

      (since C++20)
      void f() override{}// Error: not a member function void g() requires(sizeof(int)==4){}// Error: not a templated function

      The parameter types, as well as the return type of a function definition cannot be (possibly cv-qualified)incompleteclass types unless the function is defined as deleted(since C++11). The completeness check is only made in the function body, which allowsmember functions to return the class in which they are defined (or its enclosing class), even if it is incomplete at the point of definition (it is complete in the function body).

      The parameters declared in thedeclarator of a function definition arein scope within the body. If a parameter is not used in the function body, it does not need to be named (it's sufficient to use an abstract declarator):

      void print(int a,int)// second parameter is not used{std::printf("a = %d\n", a);}

      Even though top-levelcv-qualifiers on the parameters are discarded in function declarations, they modify the type of the parameter as visible in the body of a function:

      void f(constint n)// declares function of type void(int){// but in the body, the type of “n” is const int}

      Defaulted functions

      If the function definition is of syntax(3), the function is defined asexplicitly defaulted.

      A function that is explicitly defaulted must be aspecial member function orcomparison operator function(since C++20), and it must have nodefault argument.

      An explicitly defaulted special member functionF1 is allowed to differ from the corresponding special member functionF2 that would have been implicitly declared, as follows:

      • F1 andF2 may have differentref and/orexcept.
      • IfF2 has a non-object parameter of typeconst C&, the corresponding non-object parameter ofF1 maybe of typeC&.
      • IfF2 has an implicit object parameter of type “reference toC”,F1 may be an explicit object member function whoseexplicit object parameter is of (possibly different) type “reference toC”, in which case the type ofF1 would differ from the type ofF2 in that the type ofF1 has an additional parameter.
      (since C++23)

      If the type ofF1 differs from the type ofF2 in a way other than as allowed by the preceding rules, then:

      • IfF1 is an assignment operator, and the return type ofF1 differs from the return type ofF2 orF1’s non-object parameter type is not a reference, the program is ill-formed.
      • Otherwise, ifF1 is explicitly defaulted on its first declaration, it is defined as deleted.
      • Otherwise, the program is ill-formed.

      A function explicitly defaulted on its first declaration is implicitlyinline, and is implicitly constexpr if it can be aconstexpr function.

      struct S{    S(int a=0)=default;// error: default argumentvoid operator=(const S&)=default;// error: non-matching return type    ~S()noexcept(false)=default;// OK, different exception specificationprivate:int i;    S(S&);// OK, private copy constructor}; S::S(S&)=default;// OK, defines copy constructor

      Explicitly-defaulted functions and implicitly-declared functions are collectively calleddefaulted functions. Their actual definitions will be implicitly provided, see their corresponding pages for details.

      Deleted functions

      If the function definition is of syntax(4) or(5)(since C++26), the function is defined asexplicitly deleted.

      Any use of a deleted function is ill-formed (the program will not compile). This includes calls, both explicit (with a function call operator) and implicit (a call to deleted overloaded operator, special member function, allocation function, etc), constructing a pointer or pointer-to-member to a deleted function, and even the use of a deleted function in an expression that is notpotentially-evaluated.

      A non-pure virtual member function can be defined as deleted, even though it is implicitlyodr-used. A deleted function can only be overridden by deleted functions, and a non-deleted function can only be overridden by non-deleted functions.

      Ifstring-literal is present, the implementation is encouraged to include the text of it as part of the resulting diagnostic message which shows the rationale for deletion or to suggest an alternative.

      (since C++26)

      If the function is overloaded,overload resolution takes place first, and the program is only ill-formed if the deleted function was selected:

      struct T{void*operator new(std::size_t)= delete;void*operator new[](std::size_t)= delete("new[] is deleted");// since C++26}; T* p= new T;// Error: attempts to call deleted T::operator newT* p= new T[5];// Error: attempts to call deleted T::operator new[],//        emits a diagnostic message “new[] is deleted”

      The deleted definition of a function must be the first declaration in a translation unit: a previously-declared function cannot be redeclared as deleted:

      struct T{ T();};T::T()= delete;// Error: must be deleted on the first declaration

      User-provided functions

      A function isuser-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its first declaration) is defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed. Declaring a function as defaulted after its first declaration can provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base.

      // All special member functions of “trivial” are// defaulted on their first declarations respectively,// they are not user-providedstruct trivial{    trivial()=default;    trivial(const trivial&)=default;    trivial(trivial&&)=default;    trivial& operator=(const trivial&)=default;    trivial& operator=(trivial&&)=default;    ~trivial()=default;}; struct nontrivial{    nontrivial();// first declaration}; // not defaulted on the first declaration,// it is user-provided and is defined herenontrivial::nontrivial()=default;

      Ambiguity Resolution

      In the case of an ambiguity between a function body and aninitializer beginning with{ or=(since C++26), the ambiguity is resolved by checking the type of thedeclarator identifier ofnoptr-declarator :

      • If the type is a function type, the ambiguous token sequence is treated as a function body.
      • Otherwise, the ambiguous token sequence is treated as an initializer.
      using T=void();// function typeusing U=int;// non-function type T a{};// defines a function doing nothingU b{};// value-initializes an int object T c= delete("hello");// defines a function as deletedU d= delete("hello");// copy-initializes an int object with// the result of a delete expression (ill-formed)

      __func__

      Within the function body, the function-local predefined variable__func__ is defined as if by

      staticconstchar __func__[]="function-name";

      This variable has block scope and static storage duration:

      struct S{    S(): s(__func__){}// OK: initializer-list is part of function bodyconstchar* s;};void f(constchar* s= __func__);// Error: parameter-list is part of declarator
      Run this code
      #include <iostream> void Foo(){std::cout<< __func__<<' ';} struct Bar{    Bar(){std::cout<< __func__<<' ';}    ~Bar(){std::cout<< __func__<<' ';}struct Pub{ Pub(){std::cout<< __func__<<' ';}};}; int main(){    Foo();    Bar bar;    Bar::Pub pub;}

      Possible output:

      Foo Bar Pub ~Bar
      (since C++11)

      Function contract specifiers

      Function declarations andlambda expressions can contain a sequence offunction contract specifiers , each specifier has the following syntax:

      preattr (optional)(predicate) (1)
      postattr (optional)(predicate) (2)
      postattr (optional)(identifierresult-attr (optional):predicate) (3)
      1) Introduces aprecondition assertion .
      2,3) Introduces apostcondition assertion .
      2) The assertion does not bind to the result.
      3) The assertion binds to the result.
      attr - a list of attributes appertaining to the introduced contract assertion
      predicate - any expression (except unparenthesizedcomma expressions)
      identifier - the identifier that refers to the result
      result-attr - a list of attributes appertaining to the result binding


      Precondition assertion and postcondition assertion are collectively calledfunction contract assertion .

      A function contract assertion is acontract assertion associated with a function. The predicate of a function contract assertion is itspredicatecontextually converted tobool.

      The following functions cannot be declared with function contract specifiers:

      Precondition assertions

      A precondition assertion is associated with entering a function:

      int divide(int dividend,int divisor) pre(divisor!=0){return dividend/ divisor;} double square_root(double num) pre(num>=0){returnstd::sqrt(num);}

      Postcondition assertions

      A postcondition assertion is associated with exiting a function normally.

      If a postcondition assertion has anidentifier , the function contract specifier introducesidentifier as the name of aresult binding of the associated function. A result binding denotes the object or reference returned by invocation of that function. The type of a result binding is the return type of its associated function.

      int absolute_value(int num) post(r: r>=0){return std::abs(num);} double sine(double num) post(r: r>=-1.0&& r<=1.0){if(std::isnan(num)||std::isinf(num))// exiting via an exception never causes contract violationthrowstd::invalid_argument("Invalid argument");returnstd::sin(num);}

      If a postcondition assertion has anidentifier , and the return type of the associated function is (possibly cv-qualified)void, the program is ill-formed:

      void f() post(r: r>0);// Error: no value can be bound to “r”

      When the declared return type of a non-templated function contains aplaceholder type, a postcondition assertion with anidentifier  can only appear in a function definition:

      auto g(auto&) post(r: r>=0);// OK, “g” is a template auto h() post(r: r>=0);// Error: cannot name the return value auto k() post(r: r>=0)// OK, “k” is a definition{return0;}

      Contract consistency

      AredeclarationD of a function or function templatefunc must have either nocontract-specs or the samecontract-specs as any first declarationF reachable fromD. IfD andF are in different translation units, a diagnostic is required only ifD is attached to a named module.

      If a declarationF1 is a first declaration offunc in one translation unit and a declarationF2 is a first declaration offunc in another translation unit,F1 andF2 must specify the samecontract-specs , no diagnostic required.

      Twocontract-specs s are the same if they consist of the same function contract specifiers in the same order.

      A function contract specifierC1 on a function declarationD1 is the same as a function contract specifierC2 on a function declarationD2 if all following conditions are satisfied:

      • Thepredicate s ofC1 andC2 would satisfy theone-definition rule if placed in function definitions on the declarationsD1 andD2 (ifD1 andD2 are in different translation units, corresponding entities defined within eachpredicate behave as if there is a single entity with a single definition), respectively, except for the following renamings:
        • The renaming of the parameters of the declared function.
        • The renaming of template parameters of a template enclosing the declared function.
        • The renaming of the result binding (if any).
      • BothC1 andC2 have anidentifier or neither have.

      If this condition is not met solely due to the comparison of two lambda expressions thatare contained within thepredicate s, no diagnostic is required.

      bool b1, b2; void f() pre(b1) pre([]{return b2;}());void f();// OK, function contract specifiers omittedvoid f() pre(b1) pre([]{return b2;}());// Error: closures have different typesvoid f() pre(b1);// Error: function contract specifiers are different int g() post(r: b1);int g() post(b1);// Error: no result binding namespace N{void h() pre(b1);bool b1;void h() pre(b1);// Error: function contract specifiers differ//        according to the one−definition rule}
      (since C++26)

      [edit]Notes

      In case of ambiguity between a variable declaration using the direct-initialization syntax and a function declaration, the compiler always chooses function declaration; seedirect-initialization.

      Feature-test macroValueStdFeature
      __cpp_decltype_auto201304L(C++14)decltype(auto)
      __cpp_return_type_deduction201304L(C++14)return type deduction for normal functions
      __cpp_explicit_this_parameter202110L(C++23)explicit object parameters (deducingthis)
      __cpp_deleted_function202403L(C++26)deleted function with a reason

      [edit]Keywords

      default,delete,pre,post

      [edit]Example

      Run this code
      #include <iostream>#include <string> // simple function with a default argument, returning nothingvoid f0(conststd::string& arg="world!"){std::cout<<"Hello, "<< arg<<'\n';} // the declaration is in namespace (file) scope// (the definition is provided later)int f1(); // function returning a pointer to f0, pre-C++11 stylevoid(*fp03())(conststd::string&){return f0;} // function returning a pointer to f0, with C++11 trailing return typeauto fp11()->void(*)(conststd::string&){return f0;} int main(){    f0();    fp03()("test!");    fp11()("again!");int f2(std::string)noexcept;// declaration in function scopestd::cout<<"f2(\"bad\"): "<< f2("bad")<<'\n';std::cout<<"f2(\"42\"): "<< f2("42")<<'\n';} // simple non-member function returning intint f1(){return007;} // function with an exception specification and a function try blockint f2(std::string str)noexcepttry{returnstd::stoi(str);}catch(conststd::exception& e){std::cerr<<"stoi() failed!\n";return0;} // deleted function, an attempt to call it results in a compilation errorvoid bar()= delete#   if __cpp_deleted_function("reason")#   endif;

      Possible output:

      stoi() failed!Hello, world!Hello, test!Hello, again!f2("bad"): 0f2("42"): 42

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      CWG 135C++98member functions defined in class
      could not have a parameter of or return
      its own class because it is incomplete
      allowed
      CWG 332C++98a parameter could have cv-qualifiedvoid typeprohibited
      CWG 393C++98types that include pointers/references to
      array of unknown bound could not be parameters
      such types are allowed
      CWG 452C++98member initializer list was not a part of function bodyit is
      CWG 577C++98dependent typevoid could be used to
      declare a function taking no parameters
      only non-dependent
      void is allowed
      CWG 1327C++11defaulted or deleted functions could not
      be specified withoverride orfinal
      allowed
      CWG 1355C++11only special member functions could be user-providedextended to all functions
      CWG 1394C++11deleted functions could not have any parameter of
      an incomplete type or return an incomplete type
      incomplete type allowed
      CWG 1824C++98the completeness check on parameter type and
      return type of a function definition could be made
      outside the context of the function definition
      only check in the
      context of the
      function definition
      CWG 1877C++14return type deduction treatedreturn; asreturnvoid();simply deduce the return
      type asvoid in this case
      CWG 2015C++11the implicit odr-use of a deleted
      virtual function was ill-formed
      such odr-uses are exempt
      from the use prohibition
      CWG 2044C++14return type deduction on functions returningvoid
      would fail if the declared return type isdecltype(auto)
      updated the deduction
      rule to handle this case
      CWG 2081C++14function redeclarations could use return type
      deduction even if the initial declaration does not
      not allowed
      CWG 2144C++11{} could be a function body or an initializer at the same placedifferentiated by the type
      of the declarator identifier
      CWG 2145C++98thedeclarator in function definition could not be parenthesizedallowed
      CWG 2259C++11the ambiguity resolution rule regarding parenthesized
      type names did not cover lambda expressions
      covered
      CWG 2430C++98in the definition of a member function in a class definition,
      the type of that class could not be the return type or
      parameter type due to the resolution ofCWG issue 1824
      only check in the
      function body
      CWG 2760C++98the function body of a constructor did not include the initializations
      not specified in the constructor's regular function body
      also includes these
      initializations
      CWG 2831C++20a function definition with arequires-clause
      could define a non-templated function
      prohibited
      CWG 2846C++23explicit object member functions could not have out-of-class definitionsallowed
      CWG 2915C++23unnamed explicit object parameters could have typevoidprohibited

      [edit]See also

      C documentation forDeclaring functions
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/function&oldid=183023"

      [8]ページ先頭

      ©2009-2025 Movatter.jp