鉴于此模板:
template <class A>
struct Something {
... // members common to all template instantiations for all A types
SpecialType member; // but not this - I want this to be conditional...
}
...我想使用“enable_if”使SpecialType成员有条件存在;也就是说,只有在使用A = SpecialCase1或SpecialCase2类型实例化模板时。在所有其他情况下,我希望SpecialType成员丢失。
如果你想知道为什么,这是关于优化 - 即不在结构中携带无用的有效载荷。我是模板元编程的新手,但我知道我需要“enable_if”和两个“is_same” - 不确定究竟是怎么做的,但是......
编辑:使用通用C ++(即没有特定于Boost)是一件好事。
答案 0 :(得分:5)
你不需要enable_if。专门针对特殊情况的结构,并保留其余的默认实现:
template <class A>
struct Something
{
// your default implementation
};
template <>
struct Something<SpecialCase1>
{
// your SpecialCase1 implementation
};
template <>
struct Something<SpecialCase2>
{
// your SpecialCase2 implementation
};
答案 1 :(得分:5)
好吧:使用基类。
struct Empty {};
struct SpecialTypeCnt { SpecialType member; };
template <typename A>
struct Something: if_< /* cond */ , SpecialTypeCnt, Empty>::type {
};
if_
定义为:
template <typename, typename, typename E> struct if_ { typedef E type; };
template <typename T, typename E>
struct if_<std::true_type, T, E> { typedef T type; };
(你也可以专注于布尔值)
当然,你需要正确表达你的状况。
话虽如此,你可能不应该只使用struct
。相反,您应该使用class
来提供需要在member
上应用的操作。然后,您提供class Null
的默认行为和class SomeType
,其行为特定于member
。
否则你会在需要“或许”修改member
的任何地方重写条件,而且它会很快变得烦人。
答案 2 :(得分:2)
为了不复制普通会员:
定义BaseSomething类:
template <class A>
struct BaseSomething {
... // members common to all template instantiations for all A types
};
定义SpecialSomething类:
template <class A>
struct SpecialSomething {
SpecialType member;
...//SpetialType related functionality
};
定义Something类:
template <class A>
struct Something :public BaseSomething<A>{
};
template<>
struct Something<SpecialCase1>:public BaseSomething<A>{
SpecialSomething<SpecialCase1> special;
};
template<>
struct Something<SpecialCase2>:public BaseSomething<A>{
SpecialSomething<SpecialCase2> special;
};
答案 3 :(得分:1)
马蒂厄(Matthieu M)已经回答了这个问题。但是,在意识形态和优雅方面要稍微解决一点,那就是执行以下操作:
struct OptionalMembers { SpecialType member; };
template <typename T>
class Something: public conditional_t<is_same<T, SpecialCase>, OptionalMembers, tuple<>> {
};
此示例显示了仅当模板参数的类型为SpecialCase时如何添加可选成员。