2010-06-28 71 views
3

我正在將一個項目從Linux遷移到Xcode,我遇到了一個「版本」問題。我使用__ COUNTER__預處理器,但它在編譯時需要一個唯一的標識符似乎在Xcode使用的GCC 4.2不知道__ COUNTER__還有...
所以,我想知道我能做些什麼來解決這個問題?
我可以通過使用macports.org或類似的東西升級GCC爲4.3(它理解__ COUNTER__)...我很喜歡OSX,並不是很好,在linux = [
或找到另一種方式來在這種情況下,完成這個功能/變量唯一標識符的方法。我嘗試了__LINE__,但幾天之後,最終你會在不同的文件上在同一行上聲明一些東西,然後玩這個並不是那麼有生命力......__COUNTER__等價於Xcode?

任何幫助表示讚賞!

感謝,
喬納森

+1

你想解決什麼問題?我從來沒有真正看到過在單個翻譯單元之外需要唯一標識符的計數器宏。 – 2010-06-28 03:07:52

+0

我需要對項目中使用的所有類進行編目,因此可以從工廠內部即時創建這些類,因此,我得到的唯一解決方案是聲明一個值類變量,該變量在其初始化時將添加此新類聲明到工廠列表,這是全部動態的,使用lib的程序員只需使用預處理器聲明該類,它將被自動編目,並可以在飛行後使用 – Jonathan 2010-06-28 03:27:47

+0

如何((md5sum(\ __ FILE__) + __ LINE__)?(如果需要,請填寫您最喜歡的字符串代替md5sum的字符串算法) – 2010-06-29 02:04:55

回答

0

@ stinky472:我用接近你上面寫的什麼碼...

我的問題是,我是使用宏來申報項目的命名空間,所以由具有的全名稱類,就像類c一樣在:: b :: c中。
我所做的是改變了我的代碼,不依靠命名空間本身,而是在類宏聲明添加一個新的說法來告訴它使用什麼名稱空間,如:

的NewClass(A :: B,C) :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」而不僅僅是「string」)。

我們使用此解決方案作爲boost ::我們通過SDK提供的任何替代方案(因此無法使用boost,因爲它需要我們的用戶安裝boost或爲我們提供部分boost這種情況可能會導致安裝了不同版本boost的用戶發生衝突)。它不像boost :: any那樣自動,因爲它需要手動註冊支持的類型(在這方面更接近boost :: variant),但不要求我們的SDK用戶啓用RTTI,並且可以跨模塊邊界可移植地工作(I'我不確定是否可以依靠RTTI在不同的編譯器,設置和模塊中生成相同的信息 - 我懷疑它)。

現在,您可以使用這些類型相關的字符串ID。一個例子是使用它來將創建函數映射到這些字符串ID,以便您可以創建一個std :: string實例,例如,通過factory :: create(「std :: string」);請注意,這只是一個假設的情況,因爲使用工廠來創建std :: string會比較奇怪。