1

名前を取り、さまざまな名前空間から呼び出されることを意図したマクロ関数があります。この名前がグローバルに一意であることを確認したいと思います。定義は次のようになります。

#define DECLARE_NEW_MYVAR( Name ) static MyVar Name( #Name )

この静的変数に名前空間を付けたい (これが、さまざまな名前空間から呼び出されることを期待している理由です) が、MyVar のコンストラクターに渡される文字列がグローバルに一意であることも確認する必要があります。これは、この値をシリアル化し、正しく関連付ける必要があるためです。

私が成功せずに試したいくつかのこと:

強制的に一意にするには:いくつかの情報に基づいて、名前に何かを追加して強制的に一意にします

  • マクロを使用してください__COUNTER__: 私が対象としているコンパイラの 1 つには、このマクロがありません。また、マクロが呼び出される順序が同じであると仮定するのは危険です。
  • マクロを使用します__FILE__。これには、一意であることを確認するのに適したファイルパス全体がありますが、別の場所または別のマシンからコンパイルされた場合、逆シリアル化は機能しなくなります。

一意かどうかを確認するには:グローバルに一意であることは呼び出し元に任せ、そうでない場合はコンパイラに文句を言わせます。

  • 名前空間内からグローバル名前空間で何かを宣言する方法を探していたので、シンボルが一意にならない場合に少なくとも複数定義されたシンボルを引き起こすことができました。これを行う方法がわかりませんでした。

基本的に、MyVar に渡すグローバルに一意の文字列を考え出す必要があります。これは、異なるコンパイル間で変更されず、できればコード変更間で変更されないことを信頼できます (特定の呼び出しが変更されていない限り)。

誰もこれを行う方法を知っていますか?

4

1 に答える 1

1

__FILE__次のように、プロジェクト ディレクトリのプレフィックスを削除できます。

#include <cstring>
#include <iostream>

#define COMMON_PATH_PREFIX "/home/user/path/to/project/"

#define UNIQUE_IDENTIFIER() (__FILE__ + std::strlen(COMMON_PATH_PREFIX))

void someFunction(const char *identifier)
{
    std::cout << identifier << std::endl;
}

int main()
{
    someFunction(UNIQUE_IDENTIFIER());
}

これは、ビルド システムによって実行さCOMMON_PATH_PREFIXれる可能性があります。#defineたとえば、CMake を使用する場合は、単純にCMAKE_SOURCE_DIRECTORY.

std::strlen()文字列は定数であり、コンパイル時に認識されるため、への呼び出しはコンパイラによって最適化される必要があります。

もちろん、これはファイルごとに 1 つの変数のみを宣言する場合にのみ機能します。識別子に追加することもでき__LINE__ますが、コードを変更すると識別子が変更される可能性が高くなります。

于 2012-10-05T16:32:00.923 に答える