5

Sto cercando di convertire una stringa letterale C++ in un'istanza della seguente configurazione:tempo di compilazione stringa letterale come argomento di un template

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)]; 

mi si avvicinò con questi aiutanti sulla base di varie fonti per 'spacchettamento' il valore di stringa quotato nel modello sopra.

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; 
}; 

Tuttavia, quando una chiamata questa ottengo un errore di compilazione:

GCC 4.9+ rapporti: errore: 'const char (& s) [1]' non è una valida modello di argomentazione per il tipo 'const char (&) [1]' perché una variabile di riferimento non ha un indirizzo costante

Clang 3.7.1 rapporti: errore: argomento modello non di tipo si riferisce all'oggetto 'che non ha collegamento

Ho provato alcuni approcci diversi ma gli errori sono per lo più gli stessi. Cosa mi manca qui?

+1

È possibile utilizzare un'estensione GNU ([es] (https://github.com/tomilov/parser_generator/blob/master/src/main.cpp#L29)). È l'unico modo pensabile al momento. – Orient

+0

Soluzione alternativa -insoddisfacente che compila sotto gcc e clang: http://ideone.com/uKP2qj –

+0

'(void)' è C-izm. 'operator const char *' è attualmente sbagliato (a rischio di errore): potrebbe essere necessario modificare definiton di 'value' da' value [sizeof ... (C)] = {C ...}; 'a' valore [ sizeof ... (C) + 1] = {C ..., '\ 0'}; ', perché attualmente la sua correttezza dipende dalla modalità di acquisizione dell'array char sorgente. – Orient

risposta

1

Questa è una soluzione soddisfacente per soddisfare le vostre esigenze?

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

Secondo i commenti di altri, questo dipende da un'estensione GNU (letterali definiti dall'utente constexpr) che non fa parte né della corrente né della prossima Standard C++ (finora): http://cplusplus.github.io/EWG/ewg-active.html#66 –

Problemi correlati