Как я могу иметь необязательный конструктор по умолчанию? - PullRequest
3 голосов
/ 30 октября 2009

Этот класс:

template <class T>
struct A {
  A() : t(T()) {
  } 

  A(const T& t_) : t(t_) {
  }

  T t;
};

не скомпилируется, если T не имеет конструктора по умолчанию. Вот этот:

template <class T>
struct A {
  A(const T& t_) : t(t_) {
  }

  T t;
};

не будет иметь конструктора по умолчанию, даже если T имеет конструктор по умолчанию.

Я хочу иметь оба - если нет T (), я не хочу A ().

Я знаю, что SFINAE нужно использовать. И что Boost.traits и Boost.enable_if могут помочь, но я не могу заставить его работать. Кто-нибудь может дать мне пример этого простого случая?

Ответы [ 2 ]

1 голос
/ 03 ноября 2009

Функции-члены шаблонов классов создаются только при их вызове.Если вы никогда не вызываете A::A(), то код, вызывающий T::T(), не должен компилироваться в этом коде:

template <class T>
struct A {
  A() : t(T()) {
  }
  // ...
};

У вас есть проблемы с этим?Если да, то какой компилятор вы используете?

Тем не менее, если код, использующий A, вызывает его конструктор по умолчанию, то единственный выход, который я вижу, - это переместить создание T в A::A() в некоторый класс признаков:

template< typename T >
struct default_a_ traits {
  static T default_construct()
  {
    return T();
  }
};

template <class T, class Traits = default_a_traits<T> >
struct A {
  A() : t(Traits::default_construct()) {
  }
  // ...
};

Для классов, не имеющих конструктора по умолчанию, вы можете предоставить некоторый класс свойств, который предоставляет средства для создания T другим способом:

struct my_special_traits_for_b {
  static T default_construct()
  {
    return read_b_from_db();
  }
};

typedef A<B, special_traits_for_b> AB;
0 голосов
/ 31 октября 2009

Попробуйте это:

template <class T>
struct A {
  A(const T& t_ = T()) : t(t_) {
  }

  T t;
};
...