如何在包装现有 class 时使变量的 return 有效

How to make return of variable efficient when wrapping existing class

我在不引入太多开销的情况下包装现有的库,这样包装库可以 运行 与现有的库一样快。我这样做是为了使界面(语法)与我的旧代码兼容。

比如说,现有的class被称为BASE,模板化class。我将其包装如下。

        template<class T>    
        class Wrapper{
        public:
           Wrapper() : base(){};
           /* ... */

          Wrapper<T> dosomething ( const Wrapper<T>& a )
          {
          Wrapper<T> output;
          output.base = CallExistingClass(a.base);
          return output;
          }

        private:
           BASE<T>   base;
            }; 

对于没有 return 类型的任何成员函数,使用 this 或 *this 生成非常高效的代码。但是,当 return 类型的

  Wrapper<T>

是必需的,调用包装库总是慢 5-10 倍。由于它只是一个包装器 class,我需要的所有操作是提取成员变量 "base"(例如 "a.base"),使用现有 a.base 中的函数做一些事情 class,然后将结果传送到"output.base"和return"output"。

我必须确保包装器 class 与我的旧代码的旧语法匹配,return 指针不是这里的选项。我能想到的解决方法是 return-by-reference with static variable.For example,声明这种方式和 return-by-reference

      Wrapper<T>& dosomething ( const Wrapper<T>& a)
      {
      static Wrapper<T> output;
      output.base = CallExistingClass(a.base);
      return output;
      }

我想知道是否有更快的方法来做到这一点而不会招致 overhead/temporary?期待任何有用的评论。

一个简单的优化是使用初始化而不是赋值,例如

template <class... U>
Wrapper(U&&... args) : base(std::forward<U>(args)...) {}  // forward constructor  

Wrapper<T> dosomething ( const Wrapper<T>& a )
{
    Wrapper<T> output{CallExistingClass(a.base)};
    return output;
}

因为copy elision,这不仅可以避免不必要的值初始化,还可以避免任何复制操作。


此外,要在对象 a 上调用 dosomething,您应该为当前声明创建一个额外的对象(比如 w),并以 w 的形式调用它=16=]。要改善这一点,有两种方法。

(1) 注意dosomething的作用不依赖于数据成员,所以可以声明为static,例如

static Wrapper<T> dosomething ( const Wrapper<T>& a )
{
    //...
}

那么您可以在 Wrapper<T>::dosomething(a) 的形式中使用它而无需创建额外的对象。

(2) 此外,您可以使用数据成员代替参数,例如

Wrapper<T> dosomething const ()
{
    Wrapper<T> output{CallExistingClass(base)};
    return output;
}

并以 a.dosomeghing().

的形式调用它