11

C++11 では、クラスにメンバー関数があるかどうかを確認するsizeために、次のテスト ヘルパーを定義できます。

template <typename T>
struct has_size_fn
{
    typedef char (& yes)[1];
    typedef char (& no)[2];

    template <typename C> static yes check(decltype(&C::size));
    template <typename> static no check(...);

    static bool const value = sizeof(check<T>(0)) == sizeof(yes);
};

などのコンパイラ拡張機能に依存せずに C++98 でこれを行うための同様のトリックはありtypeofますか?

4

1 に答える 1

10

実際、あなたの検出は間違っている可能性があります。

問題は、検出しCているのはメンバーがあることだけですsize:

  • 属性かもしれません
  • どんなシグニチャを持つメソッドでもかまいません
  • いくつかのメソッドが存在する可能性もあります (さまざまなシグネチャを使用)

検出を強化したい場合は、(どのような権利であっても) 権利のみを検出するようにしてください sizeこれがそのような強化された検出です。

template <typename T>
class has_size {
private:
  typedef char Yes;
  typedef Yes No[2];

  template <typename U, U> struct really_has;

  template <typename C> static Yes& Test(really_has <size_t (C::*)() const,
                                        &C::size>*);

  // EDIT: and you can detect one of several overloads... by overloading :)
  template <typename C> static Yes& Test(really_has <size_t (C::*)(),
                                        &C::size>*);

  template <typename> static No& Test(...);

public:
    static bool const value = sizeof(Test<T>(0)) == sizeof(Yes);
};

編集: with overloads .

size間違ったメンバーを処理するコツはreally_has構造です。完璧だとは言いませんが…

C++11 では、物事を直接使用して検出できるため、物事はより単純です (冗長ではありませんが) 。したがって、同等の特性は次のとおりです。

template <typename T>
class has_size {
private:
  typedef char Yes;
  typedef Yes No[2];

  template<typename C> static auto Test(void*)
    -> decltype(size_t{std::declval<C const>().size()}, Yes{});

  template<typename> static No& Test(...);

public:
    static bool const value = sizeof(Test<T>(0)) == sizeof(Yes);
};

ただし、C++ で推奨される方法は、可能であれば特性を使用しないことです。たとえば、関数でdecltypeは、型シグネチャで right を使用できます。

于 2013-09-02T13:32:20.263 に答える