11

鉴于此模板:

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-specifics)将是一个加号。

4

4 回答 4

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
};
于 2012-04-13T11:56:58.587 回答
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提供需要应用的操作的a member。然后为 aclass Null提供默认行为,并为 aclass SomeType提供特定于 的行为member

否则,您将在需要“可能”修改的任何地方重写条件member,并且它会很快变得烦人。

于 2012-04-13T11:57:30.170 回答
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;
                    };
于 2012-04-13T12:18:03.140 回答
1

Matthieu M 已经回答了这个问题。但是,一个稍微更惯用和优雅的解决方案是执行以下操作:

struct OptionalMembers { SpecialType member; };

template <typename T>
    class Something: public conditional_t<is_same<T, SpecialCase>, OptionalMembers, tuple<>> {
};

此示例说明如何仅在模板参数为 SpecialCase 类型时添加可选成员。

于 2020-07-13T19:35:46.713 回答