2

環境

Boost ライブラリの UUID 実装を使用して、派生クラスを識別することがよくあります。そうするために、私は通常、以下を使用します:
宣言ファイル内:

  #include "ClassA.h"
  #include <boost/uuid/uuid.hpp>

  class SubClass1 : public ClassA {
    public:
      static const boost::uuids::uuid classId; // 7feb24af-fc38-44de-bc38-04defc3804de
    ... 
  };

実装ファイル内:

  #include "SubClass1.h"
  #include <boost/uuids/uuid_generator.h>

  const boost::uuids::uuid SubClass1 ::classId = boost::uuids::string_generator()("{7feb24af-fc38-44de-bc38-04defc3804de}");
  ...


質問

宣言ファイルの UUID に値を割り当てることができるかどうかを知りたいです。


アイデア

最初は、Boost の実装が POD だからできると思っていました。したがって、集約初期化子を使用してヘッダーに値を直接割り当てるいくつかの方法を試しました (非静的集約初期化子の例については、ブーストのドキュメントを参照してください)。

  static const boost::uuids::uuid classId = { 0x7f, 0xeb, ... };

残念ながら、コンパイルに失敗しました (コンパイラは static const 整数型しか初期化できません)。

できれば UUID の Boost 実装を使用して、この問題を解決するための提案はありますか?

4

1 に答える 1

2

ヘッダー ファイルで非整数定数をクラス メンバーとして定義する最も簡単な方法は、次のように関数でラップすることです。

typedef whatever Uuid;

class MyClass
{
public:
    static Uuid const& uuid()
    {
        Uuid const theValue = ...;
        return theValue;
    }
};

関数ではなく実際の定数として使用したい場合は、次のようなちょっとしたテンプレートのトリックを使用できます。

template< class Dummy >
class MyClass_constants
{
public:
    static Uuid const uuid;
};

template< class Dummy >
Uuid const MyClass_constants<Dummy>::uuid = ...;

class MyClass
    : public MyClass_constants<void>
{};

constexprC++11 では、次のように を使用できます。

class MyClass
{
public:
    static Uuid constexpr uuid = ...;
};

しかし、そのテストは g++ 4.7.1 でリンカ警告なしで正常にコンパイルされますが、標準の 1 つの定義規則が実際にそれをサポートしているかどうか、または複数の翻訳単位でのそのような定義で、私が未定義の動作に夢中です。

したがって、もしあなたが をしたいのであればconstexpr、おそらく ODR について別の質問をしてください。

別の方法として、C++2040 標準を待ってから書くこともできます。

inline static Uuid const uuid = ...;

示されているように、この架空の将来の機能はC++98 でもエミュレートできる、つまり、必要なものはすべてコンパイラとリンカーによって既に実装されており、最初の標準から実装されているということは、考えさせられます。それでも、その単純な機能が言語に欠けているということです。それは一種のでたらめな歴史的言語の進化によるものだと私は信じています。

とにかく、最初に示した単純な関数ラッパーを使用します。:-)

于 2012-10-18T09:35:46.987 に答える