【问题标题】:Perfect forwarding of primitive types原始类型的完美转发
【发布时间】:2015-04-22 13:00:20
【问题描述】:

我需要为自己的数据结构实现一些类似于vector::emplace 的方法。在一般情况下,我会实现它们以便它们支持完美转发,即使用右值引用、std::forward 和其他东西。

但是,如果我知道要转发的所有参数都是原始类型,例如 intfloat,该怎么办。为原始类型实现完美转发是否有意义?

也就是说,假设我们只使用原始类型作为模板参数,下面两个代码sn-ps有区别吗?

template <typename... Args>
void wrapper(Args&& ... args) {
   func(std::forward<Args>(args)...);
}

template <typename... Args>
void wrapper(Args ... args) {
   func(args...);
}

另外:如果我们知道模板参数只能是只包含原始类型的类,有什么区别吗?还是只包含原始类型的类和其他本身仅包含原始类型的类?

【问题讨论】:

  • 您的“另外”问题毫无意义。忽略分配器,一个简单的vector 实现只包含三个指针。大概你的意思是关于 POD 或类似的东西?
  • 我看不出std::vector 的实现与我的问题有什么关系。基本上,问题与向量完全无关。 “附加”问题很简单:假设所有模板参数都是仅包含原始类型作为成员的结构/类,那么两段代码之间是否存在差异。
  • 一个向量包含三个指针,指针是原始类型,所以它是一个“只包含原始类型的类”,但显然你想完美地转发一个向量。
  • 据我所知,原始类型通常表示 char、int、float 等,而不是指针或引用。参见例如msdn.microsoft.com/en-us/library/aa712840%28v=vs.71%29.aspx。 C++ 标准不知道“原始类型”这个术语。
  • 好吧,根据Wikipedia,指针和引用都包括在内。无论如何,即使类只有 int 数据成员,类的构造函数和析构函数也可以做任意复杂的事情。

标签: c++ move rvalue-reference primitive-types perfect-forwarding


【解决方案1】:

不,对基本类型使用完美转发绝对没有任何意义:

  1. 复制相当于移动它们。
  2. 复制它们的成本与通过引用传递的成本大致相同或更低(由于其他优化,尤其是指针别名)。
  3. 最好的代码是不存在的代码。

但有一个例外:
没有办法避免通过引用获取输出参数。

另外,如果您仍然在编写模板,您是否绝对确定永远不想将它用于更复杂的类型?
YAGNI(你不会需要它)非常重要,但以后不要因为不必要地限制你的界面而妨碍自己。

永远记住一句古老的格言“过早的优化是万恶之源”。

【讨论】:

  • 取决于func 是否可以引用某些内容,不是吗?
  • @T.C.:你的意思是输出参数?
  • 据我了解您的回答,在我在问题末尾描述的情况下也是有效的,对吧?
  • @user1494080:是的,在这种情况下,额外的副本可能无论如何都可以优化掉。如果没有,对于大型类型,不复制可能会更有效。自然,如果它实际上是一个外参数,则别无选择。这假定您的类型仍然是普通类型。
猜你喜欢
  • 2021-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-02
  • 1970-01-01
  • 1970-01-01
  • 2015-11-05
相关资源
最近更新 更多