5

我想一个C++文本字符串转换成以下模板的实例:编译时文字字符串作为模板参数

template <char ... C> 
struct string_literal { 
    typedef string_constant type; 
    static constexpr const char value[sizeof...(C)] = {C...}; 
    constexpr operator const char* (void) const { 
     return value; 
    } 
}; 
template <char ... C> 
constexpr const char string_literal<C...>::value[sizeof...(C)]; 

我与这些助手上前基于对“开箱”各种来源将引用的字符串值放到上面的模板中。

template <unsigned N, const char (&S) [N], typename U> 
struct selector; 

template <unsigned N, const char (&S) [N], unsigned ...I> 
struct selector<N, S, index_sequence<I...>> { 
    using type = string_literal<S[I]...>; 
}; 

template <unsigned N, const char (&S) [N]> 
struct unpack { 
    using type = typename selector<N, S, make_index_sequence<N>>::type; 
}; 

然而,当调用此我得到一个编译错误:

GCC 4.9+报道: 错误:为const char(& S)[1]“不是一个有效的对于类型模板参数“常量字符(&)[1]”,因为一个参考变量不具有恒定的地址

锵3.7.1报告: 错误:非类型模板参数指的是没有链接的对象's'

我尝试了几种不同的方法,但错误大多相同。 我在这里错过了什么?

+1

您可以使用GNU扩展([示例](https://github.com/tomilov/parser_generator/blob/master/src/main.cpp#L29))。这是目前唯一可以想象的方式。 – Orient

+0

替代-unsatisfactory-在gcc和clang下编译的解决方案:http://ideone.com/uKP2qj –

+0

'(void)'是C-izm。 'operator const char *'目前是错误的(容易出错):您可能需要将'value'的value的定义从'value [sizeof ...(C)] = {C ...};'更改为'value [ sizeof ...(C)+ 1] = {C ...,'\ 0'};',因为目前它的正确性取决于获取源字符数组的方式。 – Orient

回答

1

这是满足您需求的令人满意的解决方案吗?

template <char ... C> 
struct string_literal { 
    static constexpr const char value[sizeof...(C)] = {C...}; 
    constexpr operator const char* (void) const { 
     return value; 
    } 
    void foo() {std::cout << value << '\n';} 
}; 
template <char ... C> constexpr const char string_literal<C...>::value[sizeof...(C)]; 

template <typename CharT, CharT... Cs> 
constexpr string_literal<Cs...> operator ""_create() { 
    return {}; 
} 

int main() { 
    string_literal<'t','e','s','t'> s = "test"_create; 
    std::cout << s << '\n'; // test 
    s.foo(); // test 
} 
+1

根据其他人的意见,这取决于GNU扩展(constexpr用户定义的文字),它不是当前或下一个的一部分C++标准(到目前为止):http://cplusplus.github.io/EWG/ewg-active.html#66 –