1

コードに次の行があります。

//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

クラスA の宣言を自動的に考慮する mycode.c++の条件文が必要なので、追加の行があります。

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プリコンパイルを使用することを考えました。出来ますか?

4

2 に答える 2

3

私はこのようなことをします:

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>();

それが役立つことを願っています。

このオンライン デモを参照してください。

于 2015-01-29T15:54:22.887 に答える