模板类可以选择将初始值作为模板参数插入

Template class optionally inserting initial values in as template parameter

本文关键字:参数 插入 选择      更新时间:2023-10-16

我目前有一个类,相当于:

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 这样带有"非平凡析构函数"的类。我正在尝试做的事情是可能的,有没有办法解决这个问题。

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

正如其他人所注意到的,模板参数的每个组合都会生成完全不同的类型。讨论一个可能的解决方案(编译时类型擦除?)对于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()是一个工厂的工厂...