What does the statement
return {};
in C++11 indicate, and when to use it instead of (say)
return NULL;
or
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
}