2010-06-28 2 views
3

Я проникаю проект от Linux до Xcode, и я столкнулся с «версией» проблемой ..__COUNTER__ эквивалент на Xcode?

мне нужен уникальный идентификатор во время компиляции для моей динамической вещи, на Linux я использую __ COUNTER__ препроцессор, но кажется, что gcc 4.2, используемый в Xcode, не знает о __ COUNTER__ еще ...
Итак, мне было интересно, что я могу сделать, чтобы решить эту проблему?
Я могу обновить GCC до 4.3 (который понимает __ COUNTER__), используя macports.org или что-то в этом роде ... Я очень нуб на OSX и не очень хорошо на linux = [
или найти другой способ выполните это, в случае, метод, чтобы дать функции/переменной уникальный идентификатор. Я пробовал с __ LINE__, но через несколько дней вы в конечном итоге объявляете материал в одной строке в разных файлах, а игра с этим просто не является продуктивной ...

Любая помощь приветствуется!

Спасибо,
Джонатан

+1

Какой проблемы вы пытаетесь решить? Я никогда не видел хорошего использования макроса счетчика, который требует уникальных идентификаторов за пределами отдельной единицы перевода. –

+0

Мне нужно каталогизировать все классы, используемые в проекте, поэтому эти классы можно создавать «на лету» с завода, тем самым единственным решением, которое я получил, было объявление переменной класса значений, которая при ее инициализации добавила бы этот новый класс объявление в заводском списке, и все это динамично, программист, использующий lib, должен просто объявить класс, используя препроцессор, который будет автоматически каталогизироваться и может использоваться на лету после – Jonathan

+0

. Как насчет ((md5sum (\ __ FILE__) + __ LINE__)? (Заполните ваш любимый алгоритм хеш-кода для строк вместо md5sum, если хотите) –

ответ

0

@ stinky472: Я использую код близко к тому, что вы написали выше ...

Моя проблема заключалась в том, что я использовал макрос, чтобы объявить пространство имен проекта, поэтому, что, имея FULLNAME из класс, например класс c, находится в :: b :: c.
Что я менял свой код, чтобы не полагаться на самих пространствах имен, но добавить новый аргумент в классе макро декларации сказать, что пространство имен он использует, как:

NewClass (а :: б, в) : public d {

};

Моя проблема с счетчиком заключалась в том, что пространства имен использовались на множестве классов, таким образом, создавая одно и то же имя переменной в макросах пространства имен, и, используя новый способ выше, мне больше не нужен счетчик. .

спасибо за помощь,
Джонатана

1

мне нужно каталогизировать все классы, используемые в проекта, так что эти классы могут быть создан на лету из внутри завода [...]

Недостаточно использовать RTTI (это не плохая идея, если вам это разрешено; boost :: any делает это), как насчет просто использования строки для имен классов? Вы можете получить это через макрос.

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

Наилучшая вещь с таким подходом заключается в том, что вам не нужно беспокоиться о проблемах между единицами перевода или модулями при таком подходе. Единственное, на что вы должны обратить внимание, это конфликты имен, и в этом случае вы можете указать пространство имен, чтобы избежать их («std :: string», а не просто «строка», например).

Мы используем это решение как альтернативу boost :: любому, который мы предоставляем через наш SDK (и, следовательно, не можем использовать boost, так как это потребует от наших пользователей установки с повышением или для доставки части ускорения, в котором это может привести к конфликтам для пользователей, у которых установлены разные версии boost). Это не так автоматизировано, как boost :: any, поскольку для этого требуется ручная регистрация поддерживаемых типов (ближе к boost :: variant в этом отношении), но не требует, чтобы наши пользователи SDK включали RTTI и работали переносимо через границы модулей (I ' m не уверен, что можно полагаться на RTTI для получения одинаковой информации в разных компиляторах, настройках и модулях - я сомневаюсь в этом).

Теперь вы можете использовать эти идентификаторы строк, которые вам нравятся. Одним из примеров было бы использовать его для сопоставления функций создания с этими идентификаторами строк, чтобы вы могли создать экземпляр std :: string, например, через factory :: create («std :: string»); Обратите внимание, что это гипотетический случай для демонстрационных целей только потому, что использование фабрики для создания std :: string будет довольно странным.

Смежные вопросы