C ++ polymorphism - type of automatic determination of a derived type

I have specific code that I want to optimize. It looks like this:

function abc( string format ) {
  if (format == "a") { // this is a string, I shouldn't have used single quote, sorry for the confusion
    classx::a t;
    doit(t);
  }
  if (format == "b"){
    classx::b t;
    doit(t);
  }
  if (format == "c"){
    classx::c t;
    doit(t) 
  }
  if (format == "d"){
    classx::d t; 
    doit(t);
  }
}

Currently there are many doit () functions with a different type

function doit( classx:a ) {
   different code for a
}

function doit( classx:b ) {
   different code for b
}

... etc.

As you can see, a lot of code is replicated. However, I cannot figure out how to reduce words. Note that: doit (x) is overloaded with another type. The class a, b, c, d is derived from the class with the name "X".

I can create a pointer type classx :: X:

classx::X *t;
if (format == "a") t = new classx::a
if (format == "b") t = new classx::b
if (format == "c") t = new classx::c
if (format == "d") t = new classx::d
doit(*t)

but then you still need to write doit () for type classx :: X with a bunch of "if then" and apply to the correct type ... since C ++ cannot automatically detect and apply to the correct type.

I wonder if there is a faster / smarter way to do this. Thanks in advance.

+5
6

, :

template<class T> void innerAbc() {
    T t;
    doit(t);
}

typedef std::map<std::string, void (*)()> FuncMap;

FuncMap initHandlers() {
    FuncMap m;
    m["a"] = &innerAbc<classx::a>;
    // ... extend here
    return m;
}   

void abc(const std::string& format) {
    static const FuncMap handlers = initHandlers();
    FuncMap::const_iterator it = handlers.find(format);
    if (it != handlers.end()) 
        it->second();
}
+3

format/constructor . - , factory, . , /.

+1

, else if if, . , ...

function abc(string format) {
    if (format == 'a')
        doit(classx::a());
    else if (format == 'b')
        doit(classx::b());
    else if (format == 'c')
        doit(classx::c())
    else if (format == 'd')
        doit(classx::d());
}
+1

. "if", .

template<typename T> void forward_doit()
{
    T t;
    doit(t);
}

void func(string const& s)
{
    if (s == "a") return forward_doit<Classx::a>();
    if (s == "b") return forward_doit<Classx::b>();
    if (s == "c") return forward_doit<Classx::c>();
    // ...
}
+1

, , - . , (Javascript?), .

, , , , - !

#define FORMATTER(ltr) \
    if (format == #ltr) { \
    classx::##ltr t; \
    doit(t); \
  }

#define ELSEFORMATTER(ltr) else FORMATTER(ltr)

void abc( std::string format ) {
    FORMATTER(a)
    ELSEFORMATTER(b)
    ELSEFORMATTER(c)
    ELSEFORMATTER(d)
}
0

boost

#define MACRO(r, data, elem)                     \
if (format == '(elem)')  doit(classx::(elem)()); \
else

BOOST_PP_SEQ_FOR_EACH(MACRO, _, (a)(b)...) {
... // else condition
}

, '': ?

0

All Articles