Misplaced Pages

Trailing return type

Article snapshot taken from Wikipedia with creative commons attribution-sharealike license. Give it a read and then ask your questions in the chat. We can research this topic together.

In computer programming, a subroutine (a.k.a. function) will often inform calling code about the result of its computation, by returning a value to that calling code. The data type of that value is called the function's return type.

In the C++ programming language, a function must be declared. The C++ function's return type is specified as a part of declaring that function. A trailing return type, a syntax feature available since C++11, is like a traditional return type, except that it is specified in a different location.

Syntax

An ordinary return type is specified before the function's name. In this example of traditional C++ code, the return type of HasMultipleItems() is bool:

class CClass {
public:
    bool HasMultipleItems();
    std::vector<int> m_veciMember;
};
bool CClass::HasMultipleItems() {
    return m_veciMember.size() > 1;
}

A trailing return type is specified after the parameter list, following -> symbols:

class CClass {
public:
    auto HasMultipleItems() -> bool;
    std::vector<int> m_veciMember;
};
auto CClass::HasMultipleItems() -> bool {
    return m_veciMember.size() > 1;
}

Distinction from other language features

In modern C++, the meaning of the auto keyword will depend on its context:

  • When used in a variable's definition (e.g., auto x = 11;), the auto keyword indicates type inference. The data type for that x will be deduced from its initialization. The return type of a function can also be inferred by using auto without specifying a trailing return type (e.g.
    auto CClass::HasMultipleItems() {
        return m_veciMember.size() > 1;
    }
    
    )
  • On the other hand, there is no type inference in the HasMultipleItems() example on the previous section. That example only uses the auto keyword as a syntactic element, because a trailing return type is being used.

Rationale

Consider the task of programming a generic version of int Add(const int& lhs, const int& rhs) { return lhs + rhs; }. A proper expression of this function's return type would use the two formal parameter names with decltype: decltype(lhs + rhs). But, where a return type is traditionally specified, those two formal parameters are not yet in scope. Consequently, this code will not compile:

// This will not compile
template<typename TL, typename TR>
decltype(lhs + rhs) Add(const TL& lhs, const TR& rhs) {
    return lhs + rhs;
}

The formal parameters are in scope, where a trailing return type is specified:

template<typename TL, typename TR>
auto Add(const TL& lhs, const TR& rhs) -> decltype(lhs + rhs) {
    return lhs + rhs;
}

See also

References

  1. Stroustrup, Bjarne (2013). The C++ Programming Language (Fourth ed.). Addison-Wesley. ISBN 978-0-321-56384-2.
  2. "Function declaration". cppreference.com. C++ Reference. Retrieved 1 March 2021.
  3. "C++0x Suffix Return Types". cplusplus.com. The C++ Resources Network. Retrieved 1 March 2021.
  4. "Functions (C++)". Microsoft C++, C, and Assembler. Microsoft Corporation. Retrieved 1 March 2021.
Category: