Почему не во время компиляции вернуть nullptr как std :: string? - PullRequest
24 голосов
/ 17 июня 2019

Из-за ошибки я только что обнаружил, что этот код прекрасно компилируется с Visual Studio 17 и, возможно, с другими компиляторами. Теперь мне любопытно, почему?

#include <iostream>
#include <string>

std::string foo(){
    return nullptr;
}

int main(){
    auto s = foo();
    std::cout << s << std::endl;
}

Я мог бы представить, что это потому, что std::basic_string c'tor может быть вызван с char*, и при возврате происходит неявное преобразование из ptr в std::stringNULL в качестве аргумента, а затем с ошибкой). Я на правильном пути?

Ответы [ 2 ]

24 голосов
/ 17 июня 2019

Да, ваше предположение верно, проверка std::basic_string конструкторов # 5 будет вызвана:

basic_string( const CharT* s,
              const Allocator& alloc = Allocator() );

Обратите внимание, что передача nullptr вызывает неопределенное поведение, как указано в стандарте и примечаниях:

Поведение не определено, если [s, s + Traits::length(s)) не является допустимым диапазоном ( для Например, если s является нулевым указателем ).

13 голосов
/ 17 июня 2019

Почему он не должен компилироваться? std::string имеет следующий конструктор:

string(const CharT* s, const Allocator& alloc = Allocator());

, который создает строку с содержимым, инициализированным копией строки символов с нулевым символом в конце, на которую указывает s. Конструктор не явный, поэтому неявное преобразование из nullptr в std::string действительно возможно.

...