我编写了一个简单的特征类,用于将字符串标识符与指定类型相关联,它的使用如下:
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;
}
问题:
- 有没有人有更好的解决方案?
- 我的理解是否正确,与静态字符串常量相比,内联模板方法返回字符串通常不会产生任何额外成本?(例如将 gcc 与 -g -O 一起使用,这实际上并不意味着 -fno-inline)。