type trait pattern用于将静态字符串常量与类型相关联

时间:2012-07-01 23:09:52

标签: c++ templates traits

我编写了一个简单的traits类,用于将字符串标识符与指定的类型相关联,它的使用方式如下:

typedef someclass<double,44> someD;
template<> inline const char* 
    nametrait<someD>::name() {return "some_other_double";}

然后我可以静态地和类型安全地做 std :: cout&lt;&lt; someD ::名称()&LT;

我得到some_other_double。这是用来包装旧的 类似数据库的结构,带有更多类型的整数键 治疗,每个领域由他们自己的类型代表,和 some_other_double表示数据库中的字段名称。

这很好用,当没有时我也得到了合理的编译错误 名称已设置(在最后找到我的完整代码)。但是,我想知道是否有 一些更好的模式,以实现相同的效果。我会定义很多 像这样的对象,我真正追求的是更像

的东西
typedef someclass<double,44,"some_other_double"> someD;

但不允许像这样使用litteral字符串常量(我认为甚至在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;
}

问题:

  1. 有没有人有更好的解决方案?
  2. 我的理解是否正确,与静态字符串常量相比,返回字符串的内联模板方法通常不会有任何额外费用? (例如,使用带有-g -O的gcc,这实际上并不意味着-fno-inline)。

1 个答案:

答案 0 :(得分:1)

我不确定它是否更好,但这稍微短一些:

template <typename T,int identifier>
class someclass {
private:
   someclass(){};
public:
   static inline const char * name();
};


typedef someclass<double,44> someD;

template <> inline const char * someD::name() {return "some other double"; }