если constexpr внутри лямбды, другое поведение компилятора - PullRequest
0 голосов
/ 16 мая 2018

Рассмотрим следующий код. Если мое понимание if constexpr верно, ветвь else не должна компилироваться, поэтому z() не следует считать ошибкой.

#include <type_traits>

struct Z{};

template<typename T>
void f(T z) {
  auto lam = [z]() {
    if constexpr(std::is_same<T, Z>::value) {
    } else {
      z();
    }
  };
}

int main() {
  f(Z{});
}

В clang и gcc это компилируется; но с последним MSVC это не так. К сожалению, MSVC Goldbolt слишком стар, но на моей машине с полностью обновленной VS 2017, cl /std:c++17 дает:

Microsoft (R) C/C++ Optimizing Compiler Version 19.14.26428.1 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

if_constexpr.cpp
if_constexpr.cpp(10): error C2064: term does not evaluate to a function taking 0 arguments
if_constexpr.cpp(16): note: see reference to function template instantiation 'void f<Z>(T)' being compiled
        with
        [
            T=Z
        ]

Если удаляющая лямбда-код удаляется, код компилируется на всех трех компиляторах.

Я делаю что-то не так или не поддерживается, или это просто ошибка MSVC?

1 Ответ

0 голосов
/ 16 мая 2018

Это ошибка MSVC. Пожалуйста, отправьте отчет об ошибке.

Правило от [stmt.if] / 2 :

Во время создания экземпляра вмещающей шаблонной сущности, если условие не зависит от значения после его создания, отброшенная подстановка (если есть) не создается.

Во время создания экземпляра f<Z>, когда мы создаем условие, мы получаем true. Это не зависит от значения, поэтому подстановка отбрасывания (та, в которой мы делаем z()) не создается. Это только инстанцирование z(), которое приводит к ошибке - и это не должно происходить.

...