条件付きメンバーを使用して構造体を作成しようとしています。つまり、特定の特殊化でのみ異なるメンバーが存在します。しかし、私はこのクラスが可能な限り高速であることを望んでいます。私は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_int
isの場合false
、フィールドのm_int
サイズは 0 です (ほとんど gcc 4.7.2 で)。 - 利点: テンプレートの使用が増える (可読性が低下する) と、コンパイラがサイズ 0 のメンバーをどのように処理するかについてよくわかりません。繰り返されるコンストラクターですが、おそらくこれは回避可能です。
最善のアプローチまたは方法は何ですか?