3

プロジェクトをLinuxからXcodeに移行していますが、「バージョン」の問題が発生しました。

動的なもののためにコンパイル時に一意の識別子が必要です。Linuxでは__COUNTER__プリプロセッサを使用していましたが、Xcodeで使用されているgcc4.2はまだ__COUNTER__を認識していないようです
...私はこれを解決するためにできるでしょうか?
macports.orgなどを使用してGCCを4.3(__ COUNTER__を理解する)にアップグレードできます...私はOSXで非常に初心者であり、Linux=[ではあまり得意ではありません
。この場合、関数/変数に一意の識別子を与える方法。__ LINE__で試しましたが、数日後、同じ行で別のファイルに何かを宣言することになり、それで遊ぶのはそれほど生産的ではありません...

どんな助けでも大歓迎です!

ありがとう、
ジョナサン

4

2 に答える 2

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」)。

このソリューションは、SDKを通じて提供するboost :: anyの代わりに使用します(したがって、ユーザーがBoostをインストールする必要があるため、またはBoostの一部を出荷する必要があるため、Boostを使用できません。異なるバージョンのブーストがインストールされているユーザーの競合)。サポートされているタイプの手動登録が必要なため、boost :: anyほど自動ではありませんが(この点ではboost :: Variantに近い)、SDKユーザーがRTTIを有効にする必要はなく、モジュールの境界を越えて移植可能に機能します(I ' mさまざまなコンパイラ、設定、およびモジュール間で同じ情報を生成するためにRTTIに依存できるかどうかはわかりません-私はそれを疑っています)。

これで、これらのタイプに関連付けられた文字列IDを好きなように使用できます。1つの例は、これを使用して作成関数をこれらの文字列IDにマップし、たとえばfactory :: create( "std :: string");を介してstd::stringのインスタンスを作成できるようにすることです。ファクトリを使用してstd::stringを作成するのはかなり奇妙であるため、これはデモ目的の架空のケースであることに注意してください。

于 2010-06-29T00:44:29.993 に答える
0

@ stinky472:私はあなたが上で書いたものに近いコードを使用しています...

私の問題は、プロジェクトの名前空間を宣言するためにマクロを使用していたことでした。そのため、クラスcのように、クラスのフルネームを持つことはa :: b::cにあります。
私が行ったことは、名前空間自体に依存しないようにコードを変更することでしたが、クラスマクロ宣言に新しい引数を追加して、使用している名前空間を示します。

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

};

カウンターに関する私の問題は、名前空間が多くのクラスで使用されていたため、名前空間マクロ内に同じ変数名が作成され、上記の新しい方法を使用することで、カウンターが不要になることでした...

助けてくれてありがとう、
ジョナサン

于 2010-07-03T02:25:50.083 に答える