2017-09-07 6 views
2

je suis tombé sur un truc:trick modèle pour définir un tableau global dans l'en-tête

// This template utilizes the One Definition Rule to create global arrays in a header. 
template<typename unused=void> 
struct globals_struct 
{ 
    static const uint8 s_str_serialize_flags[256]; 
    // ... 
}; 
typedef globals_struct<> globals; 

template<typename unused> 
const uint8 globals_struct<unused>::s_str_serialize_flags[256] = 
{ 
// ... data here ... 
}; 
    // ... and then the array is accessible as: 
    uint8 value = globals::s_str_serialize_flags[index]) 

Ce code est de Rich Geldreich de Purple JSON que j'ai appris du Tchad d'Austin blog. Avant de voir ce code, je pensais que la seule façon d'avoir un tableau dans une bibliothèque en-tête uniquement est d'exiger de l'utilisateur #define une macro magique dans exactement un fichier (avant d'inclure l'en-tête).

J'aime le truc modèle d'emballage, mais je me demande:

  • est un idiome ++ C (-t-il un nom)?
  • est-il conforme aux normes et sûr à utiliser?
  • est un tel enveloppement de modèle la manière la plus simple d'avoir un tableau dans l'en-tête?

Edit: Je viens de tomber sur le même tour dans un SO answer où il est présenté comme une alternative à 17 C++ variables inline.

Répondre

1

Pour moi, le plus simple est de l'envelopper dans une fonction (et std::array)

using arr256 = std::array<std::uint8_t, 256>; 

inline constexpr arr256 s_str_serialize_flags() { 
    constexpr arr256 values = {/**/}; 
    return values; 
} 

ou sans la contrainte constexpr:

using arr256 = std::uint8_t[256]; 

inline const arr256& s_str_serialize_flags() { 
    static const arr256 values = {/**/}; 
    return values; 
} 
+0

'erreur: 'valeurs' déclarées 'statique' dans ' constexpr 'function' – marcin

+0

@marcin: Triste que ce n'était pas permis de cette façon: -/Fixe par alternative (garder le 'constexpr'). – Jarod42