What does “return {}” statement mean in C++11?

后端 未结 4 465
广开言路
广开言路 2021-01-30 02:59

What does the statement

return {};

in C++11 indicate, and when to use it instead of (say)

return NULL;

or

4条回答
  •  余生分开走
    2021-01-30 03:34

    return {}; indicates "return an object of the function's return type initialized with an empty list-initializer". The exact behaviour depends on the returned object's type.

    From cppreference.com (because the OP is tagged C++11, I excluded the rules in C++14 and C++17; refer to the link for further details):

    • If the braced-init-list is empty and T is a class type with a default constructor, value-initialization is performed.
    • Otherwise, if T is an aggregate type, aggregate initialization is performed.
    • Otherwise, if T is a specialization of std::initializer_list, the T object is direct-initialized or copy-initialized, depending on context, from the braced-init-list.
    • Otherwise, the constructors of T are considered, in two phases:

      • All constructors that take std::initializer_list as the only argument, or as the first argument if the remaining arguments have default values, are examined, and matched by overload resolution against a single argument of type std::initializer_list
      • If the previous stage does not produce a match, all constructors of T participate in overload resolution against the set of arguments that consists of the elements of the braced-init-list, with the restriction that only non-narrowing conversions are allowed. If this stage produces an explicit constructor as the best match for a copy-list-initialization, compilation fails (note, in simple copy-initialization, explicit constructors are not considered at all).
    • Otherwise (if T is not a class type), if the braced-init-list has only one element and either T isn't a reference type or is a reference type that is compatible with the type of the element, T is direct-initialized (in direct-list-initialization) or copy-initialized (in copy-list-initialization), except that narrowing conversions are not allowed.

    • Otherwise, if T is a reference type that isn't compatible with the type of the element. (this fails if the reference is a non-const lvalue reference)
    • Otherwise, if the braced-init-list has no elements, T is value-initialized.

    Before C++11, for a function returning a std::string, you would have written:

    std::string get_string() {
        return std::string();
    }
    

    Using the brace syntax in C++11, you don't need to repeat the type:

    std::string get_string() {
        return {}; // an empty string is returned
    }
    

    return NULL and return nullptr should be used when the function returns a pointer type:

    any_type* get_pointer() {
        return nullptr;
    }
    

    However, NULL is deprecated since C++11 because it is just an alias to an integer value (0), while nullptr is a real pointer type:

    int get_int() {
        return NULL; // will compile, NULL is an integer
    }
    
    int get_int() {
        return nullptr; // error: nullptr is not an integer
    }
    

提交回复
热议问题