【问题标题】:Template class optionally inserting initial values in as template parameter模板类可选地插入初始值作为模板参数
【发布时间】:2014-11-16 07:30:56
【问题描述】:

我目前有一个类相当于:

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

【问题讨论】:

  • 这不太可能达到你想要的效果; MyContainer&lt;int&gt;MyContainer&lt;int, 43&gt;完全不同的类型。这意味着如果你有一个 std::vector&lt;MyContainer&lt;int&gt;&gt;不能在没有转换运算符的情况下向这个容器添加一个MyContainer&lt;int, 43&gt; /构造函数。模板参数不应仅用于提供本质上是构造函数参数的内容;只需使用 constexpr 构造函数。
  • 您不能将std::string 用作非类型参数。
  • @RSahu 但他可以使用类型列表和用户定义的文字 + decltype 来模拟它

标签: c++ class templates


【解决方案1】:

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

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

【讨论】:

  • : _value() 隐含在默认的空实现中,不是吗?
  • @BartekBanachewicz 是的。我是零规则的忠实粉丝,但我只是修改了 OP 所做的。就算写了,还是喜欢MyContainer() = default;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-03
  • 1970-01-01
  • 1970-01-01
  • 2016-11-09
  • 1970-01-01
相关资源
最近更新 更多