如何拥有可选的默认构造函数?

3

这个类:

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可以帮助,但我无法使其正常工作。有人能给我一个这个简单案例的例子吗?


如果T没有默认构造函数,您希望A()在T上调用什么? - mmmmmm
如果没有T(),我就不需要A()。 - Łukasz Lew
4
我可能错了,但是你确定第一个失败了吗,“如果您不尝试使用没有默认构造函数的T的默认版本”? GCC和Comeau都可以正常工作。 您如何实例化该类? - UncleBens
所以你也必须处理私有默认构造函数(通常将其设置为私有以避免编译器定义)。话虽如此,我不确定你能否... - Oren S
3
"UncleBens"说,干嘛费劲呢?如果你尝试使用A()但没有T(),它会失败;如果你不尝试使用它,它就不会失败。另一个改进是:目前你的类需要T的复制构造函数,你可以通过写入t()而不是t(T())来解决这个问题。 - Johannes Schaub - litb
2个回答

1
类模板的成员函数只有在调用它们时才会实例化。如果您从未调用 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

试试这个:

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

  T t;
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接