Как я могу использовать значение constexpr в лямбде?

Я хотел бы использовать значение constexpr в лямбде. Читать ответ использование лямбда захваченного значения constexpr в качестве измерения массива, я предположил, что следующее должно работать:

  #include<array>
  int main()
  { 
    constexpr int i = 0;
    auto f = []{  
      std::array<int, i> a;
    };
    return 0;
  }

однако Clang 3.8 (с std=c++14) жалуется, что

переменная "i" не может быть неявно захвачена в лямбде без capture-по умолчанию указано

следует ли считать это ошибкой в clang 3.8?

BTW:

приведенный выше код компилируется с gcc 4.9.2. Если я изменю лямбда-выражение для захвата явно:

...
auto f = [i]{
...

clang 3.8 компилирует его, но GCC 4.9.2 терпит неудачу:

error: значение " i’ не используется в постоянном выражении ...

1 ответов


следует ли считать это ошибкой в clang 3.8?

да. Захват необходим только в том случае, если [expr.подтянутый.лямбда]/12 мандатов так:

enter image description here

обратите внимание, в частности, подчеркнул примеру. f(x) не требуется x для захвата, потому что он не используется odr (разрешение перегрузки выбирает перегрузку с параметром object). Та же аргументация применяется к вашему коду - [основной.защита.odr] / 3:

переменная x чье имя указано как потенциально-оценка выражение ex - это Усо-используется ex если не применять преобразование lvalue-в-rvalue (4.1) к x дает постоянное выражение (5.20), которое не вызывает любые нетривиальные функции...

это требование, безусловно, встречались.

...и, если x - это объект, ex элемент множество потенциальных результатов выражения e, где преобразование lvalue в rvalue (4.1) применяется к e или e - это отброшены значение выражения (п. 5).

i - это набор потенциальных результатов в основной.защита.odr] / (2.1), и преобразование l-t-r действительно немедленно применяется, поскольку оно передается параметру шаблона типа объекта не-типа.

таким образом, мы показали, что (12.1) не применимо-и (12.2)явно нет, либо-Clang ошибается в отклонении вашего фрагмента.