将 constexpr 更改为 consteval 会导致 MSVC 中出现难以理解的错误消息。编译器错误或有问题的代码?

紫罗兰长颈鹿

我有以下模板/编译时实用程序帮助函数。当一切正常时,它在所有三个编译器(MSVC、GCC、clang)中都可以正常工作constexpr,但是更改一些位会consteval导致 MSVC 出现奇怪的错误。我想尽可能多地迁移我的所有constexpr机器consteval,这个问题没有帮助。

#include <optional>
#include <tuple>
#include <type_traits>
 
template <auto v>
struct value_as_type {
    static constexpr auto value = v;
    using type = decltype(value);

    consteval operator type() const noexcept {
        return v;
    }
};

template <size_t First, size_t Last, typename Functor>
consteval void consteval_for([[maybe_unused]] Functor&& f) noexcept
{
    if constexpr (First < Last)
    {
        if constexpr (std::is_same_v<bool, std::invoke_result_t<Functor()>>)
        {
            if (f(value_as_type<First>{}) == false)
                return;
        }
        else
            f(value_as_type<First>{});

        consteval_for<First + 1, Last>(std::forward<Functor>(f));
    }
}

template <size_t index, typename... Args>
using type_by_index = std::tuple_element_t<index, std::tuple<Args...>>;

template <typename T, typename... Args>
[[nodiscard]] consteval std::optional<size_t> index_for_type() noexcept
{
    std::optional<size_t> index;
    consteval_for<0, sizeof...(Args)>([&index](auto i) {
        if (!index) // The index of the first occurrence is stored
        {
            if constexpr (std::is_same_v<T, type_by_index<static_cast<size_t>(i), Args... >> )
                index = static_cast<size_t>(i);
        }
    });

    return index;
}

static_assert(index_for_type<int, float, void, int, bool>() == 2);

错误信息是:

<source>(52): error C2440: '<function-style-cast>': cannot convert from 'initializer list' to 'std::optional<size_t>'        
<source>(52): note: Invalid aggregate initialization

我根本没有看到任何聚合初始化optional我的问题是:您认为这是 MSVC 中的错误,还是我的代码有问题?

PS 删除optional并仅返回size_t会删除错误,但我确实需要一种方法来说“包中不存在该类型”而不会出现编译错误。std::optional在语义上似乎非常适合这个。

本·沃格特

移除所有胆量后会发生同样的错误。

#include <optional>
 
[[nodiscard]] consteval std::optional<size_t> index_for_type() noexcept
{
    return 1;
}

static_assert(index_for_type() == 2);

这让我相信微软std::optional还没有consteval准备好。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章