Can I obtain C++ type names in a constexpr way?

前端 未结 2 1935
悲&欢浪女
悲&欢浪女 2020-12-03 01:13

I would like to use the name of a type at compile time. For example, suppose I\'ve written:

constexpr size_t my_strlen(const char* s)
{
        const char* c         


        
2条回答
  •  星月不相逢
    2020-12-03 01:41

    (Based on @melak47's gist and using C++17):

    #using 
    // and if it's not C++17, take the GSL implementation or just roll your own struct - 
    // you only need to implement 3 or 4 methods here.
    
    namespace detail {
    
    template
    constexpr const char* templated_function_name_getter() {
    #if defined(__GNUC__) || defined(__clang__)
        return __PRETTY_FUNCTION__;
    #elif defined(_MSC_VER)
        return __FUNCSIG__;
    #else
    #error unsupported compiler (only GCC, clang and MSVC are supported)
    #endif
    }
    
    } // namespace detail
    
    template
    constexpr std::string_view type_name() {
    
        constexpr std::string_view funcsig =  detail::templated_function_name_getter();
    
        // Note: The "magic numbers" below 
    
        #if defined(__GNUC__) || defined(__clang__)
        constexpr auto start_bit = std::string_view{"T = "};
        constexpr auto end_bit = std::string_view{"]"};
        #elif defined(_MSC_VER)
        constexpr auto start_bit = std::string_view{"detail::templated_function_name_getter<"};
        constexpr auto end_bit = std::string_view{">("};
        #else
        #error unsupported compiler (only GCC, clang and MSVC are supported)
        #endif
    
        constexpr auto start = funcsig.find(start_bit);
        constexpr auto end = funcsig.rfind(end_bit);
        static_assert(
            start != funcsig.npos and end != funcsig.npos and end > start, 
            "Failed parsing the __PRETTY_FUNCTION__/__FUNCSIG__ string");
        }
        return funcsig.substr(start + start_bit.size(), end - start - start_bit.size());
    }
    

    Note: There's now a nicer version of this approach implemented here.

提交回复
热议问题