Когда компилятор C ++ выводит ничего, кроме метода? - PullRequest
0 голосов
/ 06 июня 2018

Я просто заметил, что мое std::vector<Foo> копировало вместо перемещения его элементов при изменении размера - даже если Foo имеет ctor перемещения:

class Foo {
    // ...
    Foo(Foo&& other) : id_(other.id_), ptr_(other.ptr_), flag(other.flag)
    {
        other.flag = false;
    };
    // ...
    int   id_; 
    void* ptr_; 
    bool  flag;
}

Тогда я прочитал:

Изменение размера в std :: vector не вызывает конструктор перемещения

, что напомнило мне, что std::vector будет использовать конструкцию перемещения только в том случае, если объявлен ctor перемещения элементов noexcept.Когда я добавляю noexcept, вызывается ctor-ход.

Мой вопрос: почему, учитывая код ctor-перемещения, компилятор не определяет, что он равен noexcept?Я имею в виду, он может знать, что исключение не может быть выброшено.Кроме того, вывод стандарта noexcept запрещен стандартом или не выполняется моим конкретным компилятором?

Я использую GCC 5.4.0 в GNU / Linux.

1 Ответ

0 голосов
/ 06 июня 2018

tl; dr: компилятору не разрешено выводить noexcept

Почему, учитывая код переноса ctor, компилятор не определяет его как исключение?

Поскольку спецификация noexcept не определяется на основе объявления, а не определения.Это аналогично тому, как работает спецификация const.Компилятору не разрешено определять функцию, которая должна быть константной, даже если его реализация не изменяет никаких элементов.

не выводит ничего, кроме запрещенных стандартом

AsЯ понимаю, да:

[кроме.spec] ... отсутствие спецификации исключения в деклараторе функции, отличном от спецификации деструктора (12.4) или функции освобождения (3.7.4.2)обозначает спецификацию исключения, которая является набором всех типов.

Вывод чего-либо, отличного от набора всех типов, противоречил бы этому правилу.Конечно, когда компилятор может доказать, что ни одно исключение не может быть сгенерировано, он может оптимизировать любой код раскрутки стека в соответствии с правилом «как будто», но такие оптимизации не могут повлиять на самоанализ SFINAE.


Произошло обсуждение о возможности введения noexcept(auto), что было бы явным способом, позволяющим компилятору выводить не что иное, кроме спецификации.

...