Implement a named class

Hi everybody,

I am trying to implement some kind of named class. It would look something like this:

1
2
3
4
class MyClass
{
    virtual std::string getName() = 0;
};


and now (what doesn't pass the compilation)

1
2
3
4
5
template <std::string NAME> class MyNamedClass
{
    std::string getName() { return NAME;}

};


and so every time I would like to have a class with a name, I could just do the following:

 
FinalClass : public MyNamedClass<"FinalClass">{};


The idea is not to have to always reimplement getName(), and just do it concisely in the declaration. Any idea on how to do something like that?

Thanks,
Nicolas
It isn't something you can do with templates pre se, you'll have to generate the function with a macro.
Last edited on
The idea is not to have to always reimplement getName(), and just do it concisely in the declaration


seems like a simple class will suffice, like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class NameClass
{
   NameClass(const std:string & name) : m_name(name) {}

   std:string getName() const
   {
      return m_name;
   }

private:
   std:string   m_name;
};

// Then we can do:

FinalClass : public NameClass("FinalClass") {};
@SIK: Line 16 is not valid syntax.
@LB: Thanks - it should be:

 
class FinalClass : public NameClass("FinalClass") {};
@SIK: that's still not valid syntax - you can't use the constructor there. Also you used single colons instead of double colons for std::string.

http://ideone.com/hylK76

Please take the time to at least test your code, or warn that it is untested.
Last edited on
Why do you need to get the name of the class?
Simple:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>
#include <typeinfo>

struct named
{
    virtual ~named() = default ;
    virtual std::string name() const { return typeid(*this).name() ; }
};

namespace Detail { struct IntermediateClass : named {}; }

class FinalClass : public named {} ;

int main()
{
    Detail::IntermediateClass ic ;
    FinalClass fc ;
    std::cout << ic.name() << "    " << fc.name() << '\n' ;
}

http://coliru.stacked-crooked.com/a/b5c2d73922aaf2f2

Demangled:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <string>
#include <typeinfo>

    #ifdef __GNUG__
        #include <cxxabi.h>
        #include <memory>
        #include <cstdlib>

        std::string demangle( const char* name )
        {
            int status ;
            std::unique_ptr< char, decltype(&std::free) >
                cstr( abi::__cxa_demangle( name, nullptr, 0, &status ), &std::free ) ;
            return std::string( status == 0 ? cstr.get() : name ) ;
        }

    #elif defined _MSC_VER

        #include <cstring>

        std::string demangle( const char* name )
        {
            const auto p = std::strchr( name, ' ' ) ;
            return p ? p+1 : name ;
        }

    #else
        std::string demangle( const char* name ) { return name ; }
    #endif // __GNUG__

struct named
{
    virtual ~named() = default ;
    virtual std::string name() const { return demangle( typeid(*this).name() ) ; }
};

namespace Detail { struct IntermediateClass : named {}; }

class FinalClass : public named {} ;

int main()
{
    Detail::IntermediateClass ic ;
    FinalClass fc ;
    std::cout << ic.name() << "    " << fc.name() << '\n' ;
}

http://coliru.stacked-crooked.com/a/ce351b2160e231e5
http://rextester.com/KKFR91615
Topic archived. No new replies allowed.