2016-06-21 2 views
7

This page говорит, что функция make_optional в C++ 17 возвращает constexpr optional<...>. Я думаю (может быть, я ошибаюсь), это потребует, чтобы optional<T> имеет конструктор копирования или перемещения constexpr. Однако, this page также говорит, что это не так.C++ 17 make_optional constexpr-ness

Я не знаю, как make_optional может быть реализован, так как в настоящее время стоит проект C++ 1z. См. this post для уточнения. Есть ли способ обхода, или, может быть, это просто ошибка стандартного проекта/cppreference?

+0

В этом вопросе нет вопросов. – immibis

+0

@immibis Обновлено :) –

+1

cppreference не вызывал, что 'constexpr' из воздуха, вы знаете ... –

ответ

2

Благодаря @Yakk и @ T.C. за их объяснения. Я чувствую пример должен прояснить ситуацию:

struct wrapper { 
    int value; 

    // non-explicit constexpr constructor 
    constexpr wrapper(int v) noexcept : value(v) {} 

    // non-constexpr copy & move constructors 
    wrapper(const wrapper& that) noexcept : value(that.value) {} 
    wrapper(wrapper&& that) noexcept : value(that.value) {} 
}; 

constexpr wrapper make_wrapper(int v) 
{ 
    return {v}; 
} 

int main() 
{ 
    constexpr auto x = make_wrapper(123); // error! copy/move construction, 
              // but no constexpr copy/move ctor 

    constexpr int y = make_wrapper(123).value; // ok 
    static_assert(y == 123, "");    // passed 
} 

make_wrapper Так же успешно возвращают constexpr wrapper; это копирование/перемещение (хотя обычно это устранено компиляторами), что предотвращает компиляцию кода, поскольку нет конструктора копирования/перемещения constexpr.

Мы можем проверить constexpr -ness возвращаемого (временного) объекта wrapper, используя его значение для инициализации переменной constexpr.

1

Вы можете напрямую построить возвращаемые значения в C++ 11 с помощью return {something}; Если есть какие-то неявные ctors, которые являются constexpr, вы можете вернуть их из функции.

+0

Я считаю, что это иллюзия, вызванная копированием. Без копирования не будет компилироваться: [gcc] (https://godbolt.org/g/X3pTzv), [clang] (https://godbolt.org/g/AiqxxV). –

+0

И, как упоминалось в упомянутом мной упоминании, даже если компилятор выполняет копирование, конструктор 'constexpr' copy/move должен быть доступен (даже если он в конечном итоге не используется). –

+0

@ ZizhengTai Это ваш собственный пример, что он создает другую копию. https://godbolt.org/g/jT7mHd Инициализация списка копий не создает временные, концептуальные или иные. –

 Смежные вопросы

  • Нет связанных вопросов^_^