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 –