我可以有一個有或沒有基於模板的成員的類嗎?虛代碼:我可以自定義類是否具有基於模板參數的成員?
template <typename HasBazMember=true>
class Foo {
int bar;
ConditionallyHaveMember<int, HasBazMember> baz;
};
所以在上面我想讓Foo有會員「baz」和Foo沒有。
我可以有一個有或沒有基於模板的成員的類嗎?虛代碼:我可以自定義類是否具有基於模板參數的成員?
template <typename HasBazMember=true>
class Foo {
int bar;
ConditionallyHaveMember<int, HasBazMember> baz;
};
所以在上面我想讓Foo有會員「baz」和Foo沒有。
是的,你可以,但你必須專門化整個班級。例如:
template< bool HasBazMember = true >
class Foo {
int bar;
int baz;
};
template<>
class Foo<false> {
int bar;
};
如果可以分開的邏輯,你可以把這些成員在基類,這樣你就不用複製代碼整個類。例如,
template< bool HasBazMember >
class FooBase
{
protected:
int baz;
};
template<>
class FooBase<false>
{
// empty class
// the Empty Base Optimization will make this take no space when used as a base class
};
template< bool HasBazMember = true >
class Foo : FooBase<HasBazMember>
{
int bar;
};
或者使用Boost.CompressedPair:在C++ 11
struct empty {};
template< bool HasBazMember = true >
class Foo
{
boost::compressed_pair<
int
, typename std::conditional< HasBazMember, int, empty >::type
> bar_and_maybe_baz_too;
};
所以如果類有很多其他成員,我必須寫所有他們兩次? – zaharpopov
@zaharpopov:不一定,您可以使用_helper基類class_或_compressed pair_。 –
什麼是壓縮對? – zaharpopov
解決方案,而specialisazion:
class empty {};
template <typename T>
struct wrap { T wrapped_member; };
template <bool HasBazMember=true>
class Foo : private std::conditional<HasBazMember, wrap<int>, empty>::type {
public:
int bar;
int& baz() {
static_assert(HasBazMember, "try using baz without HasBaz");
return static_cast<wrap<int>&>(*this).wrapped_member;
}
};
int main()
{
Foo<true> t;
t.baz() = 5;
Foo<false> f;
f.baz() = 5; // ERROR
}
指出,由於EBO,沒有空間的開銷,如果HasBazMember=false
。
如果您的解決方案有條件地擁有會員,您正在解決什麼問題? – GManNickG
@GManNickG:我有一個類應該有一個緊湊的變化(更小的sizeof'),我研究可能性(使用繼承有其問題) – zaharpopov