Decrease noise syntax without using a macro

I am trying to find a way to reduce a bit of syntactic "noise" without resorting to a macro. For the following code:

struct base { base() = delete; };    
struct tag1 final : private base
{
    static constexpr const char* name = "tag1";
};
template <typename T> std::string name() { return T::name; }
// ...
int main()
{
   const std::string name1(name<tag1>());
   return 0;
}

it would be nice to get rid of some syntax static constexpr const char*(not to mention something else), since he is annoyed to repeat what for tag2, tag3etc. In addition, the only part is all that is really interesting tag1, the rest is β€œnoise”. The direct solution is to use a macro:

#define MAKE_TAG(tag_name) struct tag_name final : private base { \
    static constexpr const char* name = #tag_name; }    
MAKE_TAG(tag2);
// ...
const std::string name2(name<tag2>());

MAKE_TAG(tag2);Macro-based syntax removed all the "noise", leaving it tag2very noticeable. An added benefit of the macro is that it tag_namecan easily be turned into a string literal that prevents copy-paste errors.

"" name

template<const char* name> base { ... };
struct tag3 final : private base<"tag3"> {};

++. , answer , :

template<char... S> struct base { base() = delete;
    static std::string name() { return{ S... }; } };    
struct tag4 final : base<'t', 'a', 'g', '4'> { };
template <typename T> std::string name() { return T::name(); }

, 't', 'a', 'g', '4' "tag4".

struct base {
    const std::string name;
    base(const std::string& name) : name(name) {} };    
struct tag5 final : base { tag5() : base("tag5") {} };
template <typename T> std::string name() { return T().name; }

tag5, , . , tag5 , DRY.

(.. ) ?... ?

+6
2

, :

template<char... S>
struct base { 
    base() = delete;
    static std::string name(){
        return {S...};
    }
};

struct tag1 final : private base<'t','a','g','1'>
{using base::name;};
struct tag2 final : private base<'t','a','g','2'>
{using base::name;};

:

std::cout << tag1::name() << std::endl;
std::cout << tag2::name() << std::endl;

using base::name , . protected public, .

name() , . .

+4

, ( GCC):

    template <typename T> constexpr const char *get_type_name()
    {
        const char *name = __PRETTY_FUNCTION__;

        while (*name++ != '[');
        for (auto skip_space = 3 ; skip_space ; --skip_space)
        {
            while (*name++ != ' ');
        }

        return name;
    }

    // ...
    auto name1 = get_type_name<int>();
    auto name2 = get_type_name<tag1>();

, ']' .

constexpr, .

, .

+3

Source: https://habr.com/ru/post/1016553/


All Articles