可扩展条件语句的机制



我的代码中有这些行:

//lines in mycode.c++
  QString str = "...some id...";
       if( str == "int")
           foo< int>()
  else if( str == "QString")
           foo< QString>()
       ...

我需要创建一种机制来在此条件语句中包含自定义类型。因此,任何程序员都可以注册他的类和foo模板化函数的实现。

我想象是这样的:

//A.h -- custom class
class A { };
template< >
  void foo< A>() { ... };
DECL( A, "A"); //macro to declare class

我想要 mycode.c++ 中的条件语句,它会自动考虑类 A 的声明,因此它将有额外的行:

else if( str == "A")
    foo< A>()

我可以像这样产生这样的效果:

//common.h
  void process_id( QString str) {
       if( str == "int")
           foo< int>()
  else if( str == "QString")
           foo< QString>()
       ...
  else if( str == "A") //this lines programmer put manually
           foo< A>();
  }
//mycode.c++
  #include "common.h"
  QString str = "some_id";
  process_id( str);

但是,如果程序员忘记编辑common.h文件怎么办?

我想,也许使用C宏系统,或者以某种方式Qt预编译。可能吗?

我会做这样的事情:

void process_id(QString const & str) 
{
   auto it =  g_actions.find(str);
   if ( it != g_actions.end() )  
         (it->second)(); //invoke action
}

支持上述内容的框架实现为:

 using action_t = std::function<void()>;
 std::map<QString, action_t>  g_actions; //map of actions!
#define VAR_NAME(x)       _ ## x
#define DEFINE_VAR(x)  VAR_NAME(x)
#define REGISTER(type) char DEFINE_VAR(__LINE__) = (g_actions[#type] = &foo<type>,0)

现在,您可以将任何类注册为:

 //these lines can be at namespace level as well!
 REGISTER(A);
 REGISTER(B);
 REGISTER(C);

然后调用process_id()为:

process_id("A"); //invoke foo<A>();
process_id("B"); //invoke foo<B>();

希望有帮助。

请参阅此在线演示。

我只会创建一个函子向量:

using ProcessFunc = std::function<bool(const QString&)>;
std::vector<ProcessFunc> ids;
void process_id(QString str) {
    for (ProcessFunc& f : ids) {
        if (f(str)) {
            break;
        }
    }
    // or...
    std::any_of(ids.begin(), ids.end(), [&](const ProcessFunc& f){
        return f(str);
    });
}

您只是提供一种附加新此类ProcessFunc的方法:

template <typename T>
void register_class(const QString& name) {
    ids.emplace_back([=](const QString& str) {
        if (str == name) {
            foo<T>();
            return true;
        }
        else {
            return false;
        }
    });
}

您的具体示例是:

register_class<int>("int");
register_class<QString>("QString");
register_class<A>("A");

我想如果你真的愿意,你可以变成一个宏。

相关内容

  • 没有找到相关文章

最新更新