【问题标题】:How can I initialize a templated type to zero out POD data or default construct non-POD data?如何初始化模板类型以清零 POD 数据或默认构造非 POD 数据?
【发布时间】:2015-07-11 19:24:23
【问题描述】:

给定 C++-03 中的模板化 C++ 函数:

template <typename data>
void example(data arg) {
  // How to get POD zero initialized and non-POD, default constructor?
  data x();
  ...
}

如果模板化参数是 POD(例如,int 获得 0float 获得 0.0 等),我如何将其归零,或者对于非 POD,使用其默认构造函数?

我看到班级成员,这是作为explained here 处理的:

struct X
{
   int x;
};

X x;        //x.x is not initialized
X y = X();  //y.x is 0

但是这种情况下,变量不是类的成员,那么如何对应得到这个初始化POD类型变量和默认构造非POD类型变量的效果呢?

【问题讨论】:

  • 您是在尝试清除arg(如arg = 0; 中的某些特定类型),还是尝试声明与arg 相同类型的变量,并对其进行值初始化?如果是前者,x 在那里做什么?如果是后者,arg 在那里做什么?
  • @PiotrS。请将答案发布为答案,而不是 cmets。不过,它可能会不必要地调用复制构造函数。根据 OP 的具体目标,还有其他一些选项。
  • @hvd 然后让我们等待OP的澄清
  • @Piotr S 你在这里有正确的答案。帖子作为答案:)

标签: c++ templates c++03


【解决方案1】:

您可以使用const T&amp; data = T();。这可以保证避免复制等,T 将被初始化值,这是需要它的类型的默认构造或所有其他类型的 0。

【讨论】:

  • 我很好奇,如果 OP 需要在创建的类型上调用非 const 成员,有什么办法吗?由于实际临时构造的不是 const,因此是否会通过 const 将这个引用转换为 UB 或定义来创建非 const 引用?
  • @NirFriedman,是的,我至少有一种情况,数据不能为 const,因为它的值是有条件更新的,但我不想要可能的 UMR,因此我需要默认初始化。跨度>
【解决方案2】:

很抱歉,我什至编写了这个解决方案,但您可以使用 boost 和 type 特征来实现,从而为每个解决方案提供不同的代码路径:

template <class T>
void f(typename boost::enable_if<boost::is_pod<T>, int>::type = 0) {
  T t = T();
  g(t);
}

template <class T>
void f(typename boost::disable_if<boost::is_pod<T>, int>::type = 0) {
  T t;
  g(t);
}

template <class T>
void g(const T & t) {
  std::cerr << t.x << std::endl;
}

也许你应该使用is_trivially_constructible trait 而不是is_pod。我知道这不是很漂亮,但它应该可以工作,并且可以很好地扩展。我假设编译器会在性能方面做一些智能的事情,但如果你真的担心你可以强制 g(这是你的函数的其余部分将被实现的地方)总是内联到 f 中。

【讨论】:

  • 函数的默认模板参数是 C++11 标准的一部分,在 C++03 中不可用
【解决方案3】:
template <typename data>
void example(data arg) 
{
     arg  = 0;
}

对于非 POD-s

  1. 定义适当的复制构造函数,将此对象设置为零
  2. 重载“=”运算符

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-22
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多