C ++ 11:条件编译:成员

时间:2013-03-18 09:42:14

标签: c++ c++11 conditional-compilation

我正在尝试使用条件成员创建一个结构,这意味着,不同的成员只存在特定的特化。但是,我希望这些课程尽可能快。我已经尝试了三种不同的方式:

方式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;
 };
  • Disadventage:每个专业化的重复代码。

方式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;
 };
  • Adventage:很少代码。
  • Disadventage:使用vtables /继承/等:更多时间在构建或访问成员?但是,换句话说,我不假装使用“引用”来基类。什么是这种方法的真正冒险或不满?

方式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_intfalse时,字段m_int的大小为0(几乎为gcc 4.7.2)。
  • Adventages:更多地使用模板(降低可读性)并且我不确定编译器如何处理大小为0的成员。我不确定大小0字段在多大程度上是危险的或有意义的。重复的构造函数,但也许这是可以避免的。

最佳方法或方法是什么?

1 个答案:

答案 0 :(得分:4)

您是否考虑过继承?

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
};