模板类可选择在模板参数中插入初始值

时间:2014-11-16 07:30:56

标签: c++ class templates

我目前有一个类相当于:

template <class T>
class MyContainer
{
public:
  MyContainer():
    _value()
  {
  }

  T DoSomething();

private:
  T _value;
};

我想这样做,以便我可以输入初始值作为模板参数,如下所示:

template <class T> constexpr T GetInital()
{
  return 0;
}

template <> constexpr std::string GetInital()
{
  return "";
}

template <class T, T initial = GetInital<T>()>
class MyContainer
{
public:
  MyContainer():
    _value(initial)
  {
  }

  T DoSomething();

private:

  T _value;
};

MyContainer<std::string> string_container; // initalized to ""
MyContainer<std::string, "hello"> string_container2; // initalized to hello
MyContainer<int> int_container; // initalized to 0
MyContainer<int, 43> int_container; // initalized to 43

但它不喜欢带有“非平凡析构函数”的类,如std :: string。我正在努力做到这一点,并且有办法解决这个问题。

1 个答案:

答案 0 :(得分:3)

只需编写一个构造函数重载来进行初始化,它正是它的设计目的。

正如其他人所注意到的,每个模板参数组合都会产生完全不同的类型。并且讨论一个可能的解决方案(编译时类型擦除?)对于C ++的一个基本特性所涵盖的情况毫无意义:构造函数

template <class T>
class MyContainer
{
public:
  MyContainer():
    _value()
  {
  }

  MyContainer(const T& init):
    _value(init)
  {
  }

  T DoSomething();

private:
  T _value;
};

MyContainer<std::string> string_container;           // initalized to ""
MyContainer<std::string> string_container2{"hello"}; // initalized to hello
MyContainer<int> int_container;                      // initalized to 0
MyContainer<int> int_container{43};                  // initalized to 43

如果您想要的是typedef,其实例始终初始化为您指定的值,只需编写工厂函数:

template<typename T> 
auto make_factory( const T& init )
{
    return [=](){ return MyContainer<T>{ init }; };
}

int main()
{
    auto factory = make_factory<std::string>( "hello" );

    auto c1 = factory(); //c1 initialized to hello
    auto c2 = factory(); //c2 initialized to hello
}

实际上,make_factory()是工厂的工厂......