字符串文字作为模板参数

时间:2012-08-03 03:26:59

标签: c++ templates

c ++的这些预处理器和模板限制正在扼杀我。 目标是将字符串文字转换为整数。

template<const char* str>
inline int LiteralToInt(){
    return __COUNTER__;
}

using std::cout;

int main(){
    cout << LiteralToInt<"Hello">();
    cout << LiteralToInt<"No">();
    cout << LiteralToInt<"Hello">();
    return 0;
}

如果模板接受字符串文字,则输出为010。是否有另一种方法来获取此输出并在编译时将字符串文字转换为整数?

4 个答案:

答案 0 :(得分:3)

是的,C ++ 11的constexpr将为您完成此任务:

 constexpr int LiteralToInt(const char * str) {
      return __COUNTER__; // or whatever.
 }

答案 1 :(得分:1)

这样的事情会起作用

extern const char HELLO[] = "Hello";

然后

cout << LiteralToInt<HELLO>();

但不是文字本身。这可能不是你想要的。

您已经发现的字符串文字本身不能用作模板参数。

答案 2 :(得分:1)

使用constexpr对Richard J Ross III's answer的一点思考给了我正确的搜索关键...你在做什么是在编译时散列一个字符串。您可以在C ++ 11(但不是早期版本)中执行此操作,如here所示。

基本思想是使用这样的东西:

unsigned int constexpr const_hash(char const *input) { 
    // really simple hash function...
    return static_cast<unsigned int>(*input) 
         && static_cast<unsigned int>(*input) + hash(input+1); 
}

但您可能希望使用具有比此更强大的属性的哈希函数...

但是如果你没有使用C ++ 11,那么我之前的陈述就是:

否 - 没有办法在编译时将字符串文字转换为整数,这样所有相同的字符串都映射到所有编译单元中的相同值(并且不同的字符串映射到不同的值),缺少以某种方式处理代码。

答案 3 :(得分:0)

不幸的是,我知道无法完全按照自己的意愿行事。

你可以对字符串有任何限制吗?喜欢多少个字符?如果您可以将其限制为1-8个字符,则可以执行以下操作:

template <char Ch1, char Ch2 = '\0', char Ch3 = '\0', char Ch4 = '\0', char Ch5 = '\0', char Ch6 = '\0', char Ch7 = '\0', char Ch8 = '\0'>
struct string_hash {
    static const uint64_t value = 
        (static_cast<uint64_t>(Ch1) << 56) | 
        (static_cast<uint64_t>(Ch2) << 48) | 
        (static_cast<uint64_t>(Ch3) << 40) | 
        (static_cast<uint64_t>(Ch4) << 32) | 
        (static_cast<uint64_t>(Ch5) << 24) | 
        (static_cast<uint64_t>(Ch6) << 16) | 
        (static_cast<uint64_t>(Ch7) << 8)  | 
        (Ch8);
};

基本上,在编译时,最多8个字符到uint64_t。用法如下:

const uint64_t x = string_hash<'T', 'e', 's', 't'>::value

这将创建一个编译时数字值(可以在switch中使用,并且所有的优点)对每个字符串1-8个字符长唯一。不幸的是,唯一的缺点是你不能把它写成字符串文字,你需要把它写成char的列表