为什么这个 constexpr 函数给我错误?

Why is this constexpr-function giving me errors?

出于调试目的,我希望能够将类型的名称作为字符串获取,经过一番谷歌搜索后,我在 SO 上找到了这个答案:

C++ Get name of type in template

它提出了这个解决方案:

#include <array>
#include <cstddef>

namespace impl
{
    template <typename T>
    constexpr const auto &RawTypeName()
    {
        #ifdef _MSC_VER
        return __FUNCSIG__;
        #else
        return __PRETTY_FUNCTION__;
        #endif
    }

    struct RawTypeNameFormat
    {
        std::size_t leading_junk = 0, trailing_junk = 0;
    };

    // Returns `false` on failure.
    inline constexpr bool GetRawTypeNameFormat(RawTypeNameFormat *format)
    {
        const auto &str = RawTypeName<int>();
        for (std::size_t i = 0;; i++)
        {
            if (str[i] == 'i' && str[i+1] == 'n' && str[i+2] == 't')
            {
                if (format)
                {
                    format->leading_junk = i;
                    format->trailing_junk = sizeof(str)-i-3-1; // `3` is the length of "int", `1` is the space for the null terminator.
                }
                return true;
            }
        }
        return false;
    }

    static constexpr RawTypeNameFormat format =
    []{
        static_assert(GetRawTypeNameFormat(nullptr), "Unable to figure out how to generate type names on this compiler.");
        RawTypeNameFormat format;
        GetRawTypeNameFormat(&format);
        return format;
    }();
}

// Returns the type name in a `std::array<char, N>` (null-terminated).
template <typename T>
[[nodiscard]] constexpr auto CexprTypeName()
{
    constexpr std::size_t len = sizeof(impl::RawTypeName<T>()) - impl::format.leading_junk - impl::format.trailing_junk;
    std::array<char, len> name{};
    for (std::size_t i = 0; i < len-1; i++)
        name[i] = impl::RawTypeName<T>()[i + impl::format.leading_junk];
    return name;
}

template <typename T>
[[nodiscard]] const char *TypeName()
{
    static constexpr auto name = CexprTypeName<T>();
    return name.data();
}
template <typename T>
[[nodiscard]] const char *TypeName(const T &)
{
    return TypeName<T>();
}

答案的得分为 10,因此我认为该代码适用于大多数人,但目前我在尝试 运行 时遇到错误。

Error C2131 expression did not evaluate to a constant 指向行 inline static constexpr RawTypeNameFormat format =

Error (active) E1763 a lambda is not allowed in a constant expression 指向行 []{,就在第一个错误的行下方。

是什么导致了这些错误?是不是我的编译器对于这些功能来说太旧了?

示例代码仅 运行C++17 或更高版本。

您似乎正在使用 Visual Studio。如果是这样,您可以转到 Project Protities 并进行以下更改以使您的代码 运行 正确。