Voici mon problème: dans un en-tête je définir un modèle de structure type_to_string
, qui vise à définir une chaîne correspondant à un argument de type donné:Définir un symbole dans un autre espace de noms
namespace foo {
template <typename T>
struct type_to_string
{
static const char * value;
};
}
template <typename T>
const char * foo::type_to_string<T>::value = "???";
Je définissent également une valeur par défaut pour la chaîne.
Maintenant, je veux utiliser une macro pour définir de nouveaux types:
#define CREATE_ID(name) \
struct name; \
\
template<> \
const char * foo::type_to_string<name>::value = #name;
Le problème est que je voudrais la macro pour être utilisable dans les espaces de noms, comme dans:
namespace bar
{
CREATE_ID(baz)
}
ce qui n'est pas possible car type_to_string<T>::value
doit être défini dans un espace de noms englobant foo
.
Voici les erreurs de compilation je reçois:
[COMEAU 4.3.10.1] error: member "foo::type_to_string<T>::value [with T=bar::baz]"
cannot be specialized in the current scope
[VISUAL C++ 2008] error C2888: 'const char *foo::type_to_string<T>::value' :
symbol cannot be defined within namespace 'bar'
with
[
T=bar::baz
]
Étrangement, GCC 4.3.5 (version MinGW) ne produit pas d'erreurs. Est-ce que quelqu'un sait une solution de contournement pour cela, peut-être en utilisant des règles de recherche que je ne connais pas (ie déclarer type_to_string
dans la macro pour que chaque espace de noms ait sa propre version, ou quelque chose comme ça)?
Merci pour le paragraphe de la norme, il est toujours bon d'avoir les exigences exactes. En ce qui concerne votre deuxième solution, c'est en fait quelque chose que je fais déjà: j'ai deux paramètres, un pour définir l'espace de noms, l'autre pour le type. Cependant, je souhaite que la macro puisse être utilisable dans un autre espace de noms, afin de ne pas restreindre le nombre d'espaces de noms utilisés. Je pourrais définir la macro CREATE_ID avec les paramètres 1, 2, 3, ... pour accepter plusieurs noms d'espace de noms, mais cela serait plutôt fastidieux. Si c'est la seule solution, je n'aurai pas beaucoup de choix ... –
Pour l'anecdote, j'ai fini par utiliser Boost.Preprocessor pour passer une liste d'espaces de noms à la macro. De cette façon, le nom peut être inclus dans plusieurs espaces de noms imbriqués. –