代码之家  ›  专栏  ›  技术社区  ›  jcai

如果lambda中有constexpr,则编译器行为不同

  •  5
  • jcai  · 技术社区  · 8 年前

    考虑以下代码。如果我的理解 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来说,情况并非如此。不幸的是,goldbolt的MSVC太旧了,但在我的机器上,完全更新了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
            ]
    

    如果删除了封闭的lambda,那么代码将在所有三个编译器上编译。

    我是做错了还是不受支持,还是只是一个MSVC bug?

    1 回复  |  直到 8 年前
        1
  •  4
  •   Barry    8 年前

    这是一个MSVC错误。请提交错误报告。

    规则,来自 [stmt.if]/2 ,是:

    在封闭模板实体的实例化过程中,如果条件在实例化后不依赖于值,则不会实例化丢弃的子状态(如果有)。

    在实例化 f<Z> ,当我们实例化得到的条件时 true 。这不是依赖于值的,所以discard子语句 z() )未实例化。这只是 z() 这导致了错误,而这不应该发生。