【问题标题】:MSVC does not respect constexpr if within lambdas如果在 lambdas 内,MSVC 不尊重 constexpr
【发布时间】:2018-04-26 10:59:12
【问题描述】:

我所指的一个例子:

#include <type_traits>

void voidFunction() {}

template <typename Function>
void lambdaTest(Function func) {
    [func]() -> void {
        int someInt;
        if constexpr (std::is_same_v<std::invoke_result_t<Function>, int>) {
            someInt = std::invoke(func);
        } else {
            std::invoke(func);
        }
    };
}

int main(int argc, char** argv) {
    lambdaTest(&voidFunction);
    return 0;
}

这在 gcc 7.2 中编译。但是,使用 MSVC 19.11.25547 我收到此错误:
error C2440: '=': cannot convert from 'void' to 'int'

这段代码在两个编译器上都能正常编译:

#include <type_traits>

void voidFunction() {}

template <typename Function>
void nonLambdaTest(Function func) {
    int someInt;
    if constexpr (std::is_same_v<std::invoke_result_t<Function>, int>) {
        someInt = std::invoke(func);
    } else {
        std::invoke(func);
    }
}

int main(int argc, char** argv) {
    nonLambdaTest(&voidFunction);
    return 0;
}

在我看来,MSVC 似乎只是忽略了 constexpr if。这是 MSVC 中的错误,还是 constexpr 如果在 lambdas 中正式禁止?

【问题讨论】:

  • 可能是编译器错误,这种支持是全新的。我想如果你在单独的函数中有 lambda 捕获和 constexpr if 它可以正常工作? template &lt;typename Function&gt; void lambdaTest(Function func) { var lambda = [func](){ nonLambdaTest(func) }; lambda(); }
  • 假设decltype(Function()) 应该产生返回的函数类型,我认为decltype(Function()) 应该是decltype(::std::declval&lt;Function&gt;()()),因为Function 的类型将是指向函数的指针。所以这段代码似乎在这两种情况下都被破坏了。
  • @VTT - 你是对的。抱歉,我在测试中使用了 invoke_result 并用 decltype 愚弄并不小心复制了错误的。在文本中修复它
  • 我从微软开发社区链接到这个问题:developercommunity.visualstudio.com/content/problem/229226/…

标签: c++ gcc visual-c++ lambda


【解决方案1】:

我已经稍微简化了这个例子(或者至少让它更明显):

#include <type_traits>
#include <utility>

template<typename TPointerToFunction>
void lambdaTest(TPointerToFunction)
{
    []() -> void // comment this line to make it work
    {
        constexpr const bool returns_int
        {
            std::is_same_v
            <
                int
            ,   decltype(::std::declval<TPointerToFunction>()())
            >
        };
        static_assert(!returns_int);
        if constexpr(returns_int)
        {
            static_assert(returns_int, "how did we get here?");
        }
    };
}

void voidFunction(void) {}

int
main()
{
    lambdaTest(&voidFunction);
    return(0);
}

【讨论】:

    猜你喜欢
    • 2019-10-14
    • 2013-08-27
    • 2020-05-21
    • 2016-08-30
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多