簡體   English   中英

為什么這個 constexpr 函數給我錯誤?

[英]Why is this constexpr-function giving me errors?

出於調試目的,我希望能夠以字符串形式獲取類型的名稱,經過一番谷歌搜索后,我在 SO 上找到了這個答案:

C++ 獲取模板中的類型名稱

它提出了這個解決方案:

#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指向行[]{ Error (active) E1763 a lambda is not allowed in a constant expressionError (active) E1763 a lambda is not allowed in a constant expression ,該行就在第一個錯誤行的正下方。

是什么導致了這些錯誤? 是不是我的編譯器對於這些功能來說太舊了?

示例代碼僅在 C++17 或更高版本下運行。

您似乎正在使用 Visual Studio。 如果是這樣,您可以轉到Project Protities並進行以下更改以使您的代碼正常運行。

2021-06-20_00.png

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM