2010-06-28 6 views
3

Je migrez un projet de Linux à Xcode et j'ai rencontré un problème « version » ..__COUNTER__ équivalent sur Xcode?

J'ai besoin d'un identifiant unique au moment de la compilation pour mes affaires dynamique, sur linux j'utilisais le __ COUNTER__ préprocesseur, mais semble que le gcc 4.2 utilisé dans Xcode ne sait pas encore __ COUNTER__ ...
Alors, je me demandais ce que je pouvais faire pour résoudre ce problème?
Je peux mettre à jour le GCC à 4.3 (qui comprend __ COUNTER__), en utilisant le macports.org ou quelque chose comme ça ... Je suis très Noob sur OSX et pas très bon sur Linux = [
ou trouver un autre moyen de accomplir ceci, dans le cas, une méthode pour donner à la fonction/variable un identifiant unique. J'ai essayé avec __ LINE__ mais après quelques jours, vous finissez par déclarer des choses sur la même ligne sur des fichiers différents, et jouer avec ce n'est pas tellement produtif ...

Toute aide est appréciée!

Merci,
Jonathan

+1

Quel est le problème que vous essayez de résoudre? Je n'ai jamais vraiment vu une bonne utilisation de la macro de compteur qui nécessite des identifiants uniques en dehors d'une seule unité de traduction. –

+0

Je dois cataloguer toutes les classes utilisées dans un projet, donc ces classes peuvent être créées à la volée dans une usine, par cela, la seule solution que j'ai eu était de déclarer une variable de classe de valeur qui ajouterait cette nouvelle classe à son initialisation déclaration à la liste d'usine, et tout cela est dynamique, le programmeur utilisant la bibliothèque suffit de déclarer la classe en utilisant le préprocesseur qu'il sera catalogué automatiquement et peut être utilisé à la volée après – Jonathan

+0

Que diriez-vous de ((md5sum (\ __ FILE__) + __ LINE__)? (Remplissez votre algorithme de code de hachage préféré pour les chaînes au lieu de md5sum si vous voulez) –

Répondre

0

@ stinky472: utiliser un code proche de ce que vous avez écrit ci-dessus ...

Mon problème était que j'utilisais une macro pour déclarer les espaces de noms d'un projet, donc par là, ayant la fullname du classe, comme la classe c est dans a :: b :: c.
Ce que je ne changeais mon code pour ne pas compter sur les espaces de noms elle-même, mais ajouter un nouvel argument à la déclaration macro de classe pour dire ce que l'espace de noms qu'il utilise, comme:

newclass (a :: b, c) : public d {

}; Mon problème avec counter était que les espaces de noms étaient utilisés sur beaucoup de classes, créant ainsi le même nom de variable dans les macros namespaces, et en utilisant la nouvelle manière ci-dessus, je n'ai plus besoin du compteur. .

merci pour l'aide,
Jonathan

1

Je dois cataloguer toutes les classes utilisées dans un projet, de sorte que ces classes peuvent être créé à la volée à partir d'une usine [...]

En plus d'utiliser RTTI (ce qui n'est pas une mauvaise idée si vous êtes autorisé à le faire, boost :: any le fait), qu'en est-il de l'utilisation de la chaîne pour les noms de classe? Vous pouvez récupérer ceci à travers une macro.

#include <iostream> 
#include <string> 
using namespace std; 

template <class T> 
const char* my_type_id() 
{ 
    return "Unknown"; 
} 

#define REGISTER_TYPE(some_type)   \ 
    template <> inline      \ 
    const char* my_type_id<some_type>()  \ 
    {          \ 
     return #some_type;     \ 
    } 

REGISTER_TYPE(int) 
REGISTER_TYPE(std::string) 

int main() 
{ 
    // displays "int" 
    cout << my_type_id<int>() << endl; 

    // displays "std::string" 
    cout << my_type_id<string>() << endl; 

    // displays "Unknown" - we haven't registered char 
    cout << my_type_id<char>() << endl; 
} 

La chose la plus intéressante avec cette approche est que vous n'avez pas à vous soucier des problèmes entre les unités de traduction ou les modules avec cette approche. La seule chose à surveiller est le conflit de noms, auquel cas vous pouvez spécifier un espace de noms pour les éviter ("std :: string" par opposition à simplement "string", par exemple). Nous utilisons cette solution comme une alternative pour boost :: tout ce que nous fournissons via notre SDK (et donc ne pouvons pas utiliser boost car il faudrait que nos utilisateurs aient un boost installé ou pour que nous envoyions des parties de boost dans lesquelles Dans le cas contraire, cela pourrait entraîner des conflits pour les utilisateurs ayant des versions différentes de boost installées). Il n'est pas aussi automatique que boost :: car il requiert un enregistrement manuel des types supportés (plus proche de boost :: variant à cet égard), mais ne nécessite pas que les utilisateurs du SDK aient activé RTTI et fonctionne de manière portative à travers les limites des modules. Je ne sais pas si on peut compter sur RTTI pour produire la même information sur différents compilateurs, paramètres et modules - j'en doute).

Maintenant, vous pouvez utiliser ces ID de chaîne associés au type, comme vous le souhaitez. Un exemple serait de l'utiliser pour mapper des fonctions de création à ces ID de chaîne afin de pouvoir créer une instance de std :: string, par exemple, via factory :: create ("std :: string"); Notez qu'il s'agit d'un cas hypothétique à des fins de démonstration uniquement car l'utilisation d'une fabrique pour créer std :: string serait plutôt étrange.