tags:

views:

194

answers:

2

This class:

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

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

  T t;
};

won't compile if T doesn't have default constructor. This one:

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

  T t;
};

won't have default constructor even if T has default constructor.

I want to have both - If there's no T() I want no A().

I know that SFINAE have to be used. And that Boost.traits and Boost.enable_if can help, but I can't get it to work. Can Someone give me an example to this simple case?

A: 

Try this:

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

  T t;
};
sellibitze
+1  A: 

Member functions of class templates are only instantiated if you invoke them. If you never invoke A::A(), then the code invoking T::T() shouldn't be compiled in this code:

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

Are you having trouble with this? If so, which compiler are you using?

That said, if the code using A invokes its default constructor, then the only way out I see is to move the creation of the T within A::A() into some traits class:

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()) {
  }
  // ...
};

For classes not having a default constructor you can provide some traits class that provide means to create a T some other way:

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

typedef A<B, special_traits_for_b> AB;
sbi