文字列識別子を指定されたタイプに関連付けるための単純なトレイトクラスを作成しました。これは次のように使用されます。
typedef someclass<double,44> someD;
template<> inline const char*
nametrait<someD>::name() {return "some_other_double";}
次に、静的かつタイプセーフにstd :: cout << someD :: name()<を実行できます。
そして私は得るsome_other_double
。これは、古いデータベースのような構造を整数キーでラップして、よりタイプセーフな処理を行うために使用されます。各フィールドは独自のタイプで表され
some_other_double
、はデータベース内のフィールド名を表します。
これは正常に機能し、名前が設定されていない場合にも妥当なコンパイルエラーが発生します(最後に完全なコードを見つけてください)。しかし、同じ効果を達成するためのより良いパターンがあるのではないかと思います。私はこれらのような多くのオブジェクトを定義します、そして私が本当に求めているのはもっと似たようなものです
typedef someclass<double,44,"some_other_double"> someD;
ただし、リテラル文字列定数をこのように使用することは許可されていません(c ++ 11でも使用できないと思います)。私が一人でこのコードに取り組んでいた場合、おそらくマクロを使用しますが、それを守ることにそれほど熱心ではありません
#define namedtype(ss,tt,id,nn,newname)\
typedef ss<tt,id> newname; \
template<> inline const char* nametrait<newname>::name() {return nn;}
また、次の行に沿って静的な名前定数を指定することも試みました。
template<>
const char * someclass<double,44>::name = "some_other_double";
しかし、上記よりも多くのテキストがなければ、一度だけ定義されていることを確認することはできないと思います(cppファイルで宣言されたものごとにテンプレートのインスタンス化を強制する必要があります)。リンクエラーよりもコンパイル時エラーの方が好きです。
これが私のコードです:
// file: mytypes.h (I omit the include guard)
// this is the default which generates an error message on looking up
// MISSING_DEFINITION_OF_name
template <typename T>
class nametrait
{
public:
static inline const char* name() {return T::MISSING_DEFINITION_OF_name();};
};
template <typename T,int identifier>
class someclass {
private:
someclass(){};
public:
static const char * name() {return nametrait<someclass>::name() ;};
};
typedef someclass<double,44> someD;
template<> inline const char* nametrait<someD>::name() {return "some other double";}
typedef someclass<int,55> someI;
template<> inline const char* nametrait<someI>::name() {return "some specific int";}
typedef someclass<char,22> someC;
template<> inline const char* nametrait<someC>::name() {return "some specific char";}
typedef someclass<char,5> someC;
template<> inline const char* nametrait<someC>::name() {return "some other char";}
使用する:
// file:: main.cpp
#include mytypes.h
int main(){
std::cout << someI::name()<<std::endl;
std::cout << someD::name()<<std::endl;
std::cout << someC::name()<<std::endl;
std::cout << someC2::name()<<std::endl;
}
質問:
- 誰かがより良い解決策を持っていますか?
- 静的な文字列定数と比較して、通常、インラインテンプレートメソッドが文字列を返すための追加コストは発生しないという私の理解は正しいですか?(たとえば、-g -Oを指定してgccを使用します。これは、実際には-fno-inlineを意味しません)。