4

条件付きメンバーを使用して構造体を作成しようとしています。つまり、特定の特殊化でのみ異なるメンバーが存在します。しかし、私はこのクラスが可能な限り高速であることを望んでいます。私は3つの異なる方法でそれを試しました:

方法 1:

 template<typename T, bool with_int = false>
 struct foo
 {
     template<typename... Args>
     foo(Args&&... args) : m_t(forward<Args>(args)...)
     {}

     T m_t;
 }

 template<typename T>
 struct foo<T, true>
 {
     template<typename... Args>
     foo(Args&&... args) : m_t(forward<Args>(args)...), m_id(0)
     {}

      T m_t;
      int m_id;
 };
  • 不利な点: 専門分野ごとにコードが繰り返されます。

方法 2:

 template<typename T, bool with_int = false>
 struct foo
 {
     template<typename... Args>
     foo(Args&&... args) : m_t(forward<Args>(args)...)
     {}

     virtual ~foo() {}

     T m_t;
 }

 template<typename T>
 struct foo<T, false> : public foo<T>
 {
      using foo<T>::foo;

      int m_id = 0;
 };
  • 利点: コードが少ない。
  • 不利な点: vtables/inheritance/etc の使用: 構築またはメンバーへのアクセスにより多くの時間がかかりますか? しかし、別の言い方をすれば、基本クラスへの「参照」を使用するふりはしません。このアプローチの本当の利点または欠点は何ですか?

方法 3

 using nil_type = void*;
 using zero_type = nil_type[0];

 template<typename T, bool with_int = false>
 struct foo
 {
    template<typename... Args, typename = typename enable_if<with_int>::type>
    foo(Args&&... args) : m_t(forward<Args>(args)...), m_int(0)
    {}

    template<typename... Args, typename = typename enable_if<!with_int>::type>
    foo(Args&&... args) : m_t(forward<Args>(args)...)
    {}        

    T m__t;
    typename conditional<with_int, int, zero_type>::type m_int;
 };
  • Ventages: コードを一度書く。with_intisの場合false、フィールドのm_intサイズは 0 です (ほとんど gcc 4.7.2 で)。
  • 利点: テンプレートの使用が増える (可読性が低下する) と、コンパイラがサイズ 0 のメンバーをどのように処理するかについてよくわかりません。繰り返されるコンストラクターですが、おそらくこれは回避可能です。

最善のアプローチまたは方法は何ですか?

4

1 に答える 1

5

相続を考えましたか?

template< bool >
struct foo_int_base
{
  // stuff without the int
  void f(); // does not use m_id
};

template<>
struct foo_int_base< true >
{
  // stuff with the int
  int m_id = 0;
  void f(); // uses m_id
};

template< typename T, bool with_int = false >
struct foo : foo_int_base< with_int >
{
  // common stuff here
};
于 2013-03-18T09:51:45.467 に答える