在c ++中,这个丑陋的构造有什么好的替代方案?

yeg*_*256 14 c++

这是我的代码(简化现实生活中的问题):

class Foo {
public:
  void f(const string& s) {
    if (s == "lt") {
      return lt();
    } else if (s == "lte")
      return lte();
    } else if (s == "gt")
      return gt();
    } else if (s == "gte")
      return gte();
    }
  }
  void lt() { /* skipped */ }
  void lte() { /* skipped */ }
  void gt() { /* skipped */ }
  void gte() { /* skipped */ }
};
Run Code Online (Sandbox Code Playgroud)

这就是我用PHP/Python/JavaScript /许多其他语言(PHP中的例子)的方法:

class Foo {
  function f($s) {
    return $this->$s();
  }
  function lt() { /* skipped */ }
  function lte() { /* skipped */ }
  function gt() { /* skipped */ }
  function gte() { /* skipped */ }
}
Run Code Online (Sandbox Code Playgroud)

如何使我的C++代码像这个PHP示例一样优雅?提前致谢.

Ale*_* C. 37

C++中没有反映.但是,像a std::map<std::string, void (Foo::*)()>这样的东西应该可以解决问题.


编辑:这是一些丑陋的代码,可以维护.请注意以下事项:

  • 这可以以各种方式改进
  • 请添加代码以处理不存在的令牌.我没有做错误检查.

#define BEGIN_TOKEN_MAP \
template <int n> \
struct add_to_ \
{ \
    static void act() {} \
}; \
std::map<std::string, void (Foo::*)()> map_;


#define DECLARE_TOKEN(str, n) \
template <> struct add_to_<n> \
{ \
    static void act() { map_[#str] = &Foo::##str; add_to<n+1>::act();} \
};\
void str()

#define END_TOKEN_MAP \
void init_map() { add_to_<0>::act(); } \
void process_token(std::string s) { (this->*map_[s])(); }


class Foo
{
    BEGIN_TOKEN_MAP
    DECLARE_TOKEN(lt, 0) { ... }
    DECLARE_TOKEN(gt, 1) { ... }
    ...
    END_TOKEN_MAP

    Foo() { init_map(); }
    void f(const std::string& s) { process_token(s); }
};
Run Code Online (Sandbox Code Playgroud)


the*_*oid 12

你可以使用dispatch table像:

typedef struct {
    char *name;
    void (*handler)();
} handler_t;

handler_t *handlers = {
    {"lt", &lt},
    {"lte", &lte},
    {"gt", &gt},
    {"gte", &gte},
    (NULL, NULL}
};

void f(const string &s) {
    for (int i=0; handlers[i].handler; ++i) {
        if (0 == strcmp(s.c_str(), handlers[i].name)) {
            handlers[i].handler();
            return;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

另请参阅此问题:如何使用您选择的语言实现调度表?

  • std :: map有什么问题?我们在谈论c ++ (3认同)

Phi*_*ipp 5

C++不是动态的,因此没有确切的等价物.更优雅的是使用地图和可能的功能对象.