Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 延迟初始化与转发_C++_C++11_Perfect Forwarding - Fatal编程技术网

C++ 延迟初始化与转发

C++ 延迟初始化与转发,c++,c++11,perfect-forwarding,C++,C++11,Perfect Forwarding,采用可能具有以下接口的“惰性”构造函数: template<class T> struct LazyConstruct { // accept any number of arguments, // which would later be used to construct T template<class... U> LazyConstruct(U&&... u) { // store the arguments

采用可能具有以下接口的“惰性”构造函数:

template<class T>
struct LazyConstruct {
   // accept any number of arguments, 
   // which would later be used to construct T
   template<class... U>
   LazyConstruct(U&&... u) {
       // store the arguments somehow
   }
   T& get() {
      if(!data) data.reset( new T( /* unpack the arguments */ ) );
      return *data;
   }
private:
   std::unique_ptr<T> data;
};
模板
结构懒散构造{
//接受任意数量的参数,
//之后将用于构造T
模板
懒散构造(U&&…U){
//以某种方式存储参数
}
T&get(){
if(!data)data.reset(新的T(/*解包参数*/);
返回*数据;
}
私人:
std::唯一的ptr数据;
};

实现这一点的好方法是什么

我不确定您的问题,但是对于延迟初始化,我建议您使用类似于
boost::optional
的东西。您可以使用它延迟初始化,并且不会使用指针和堆内存

class MyClass {
public:
    void f();
};

void anotherFunc(MyClass & c);

boost::optional<MyClass> mc; //Not initialized, empty, stack memory.

mc = MyClass{};
if (mc != boost::none)
    mc->f();
anotherFunc(*mc);
class-MyClass{
公众:
无效f();
};
无效另一个功能(MyClass&c);
boost::可选mc//未初始化,堆栈内存为空。
mc=MyClass{};
如果(mc!=boost::none)
mc->f();
另一个函数(*mc);

文档在这里:

我不确定您的问题,但是对于延迟初始化,我建议您使用类似于
boost::optional
的东西。您可以使用它延迟初始化,并且不会使用指针和堆内存

class MyClass {
public:
    void f();
};

void anotherFunc(MyClass & c);

boost::optional<MyClass> mc; //Not initialized, empty, stack memory.

mc = MyClass{};
if (mc != boost::none)
    mc->f();
anotherFunc(*mc);
class-MyClass{
公众:
无效f();
};
无效另一个功能(MyClass&c);
boost::可选mc//未初始化,堆栈内存为空。
mc=MyClass{};
如果(mc!=boost::none)
mc->f();
另一个函数(*mc);

文档在这里:

最简单的方法可能是只捕获lambda中的参数

template<class T>
struct LazyConstruct {
   // accept any number of arguments, 
   // which would later be used to construct T
   template<class... U>
   LazyConstruct(U&&... u)
       : create( [=]() -> T* { return new T(u...); } ) 
   {}
   T& get() {
      if(!data) data.reset( data.reset( create() ) );
      return *data;
   }
private:
   std::unique_ptr<T> data;
   std::function<auto()->T*> create;
};
模板
结构懒散构造{
//接受任意数量的参数,
//之后将用于构造T
模板
懒散构造(U&&…U)
:create([=]()->T*{返回新的T(u..;})
{}
T&get(){
如果(!data)data.reset(data.reset(create());
返回*数据;
}
私人:
std::唯一的ptr数据;
std::function*>create;
};
免责声明:编译器的手不能触摸代码


注意:虽然我现在无法确切地说出这个想法的错误(已经很晚了),但不知何故,懒惰的创作闻起来并不正确。我怀疑是过早优化。

最简单的方法可能是在lambda中捕获参数

template<class T>
struct LazyConstruct {
   // accept any number of arguments, 
   // which would later be used to construct T
   template<class... U>
   LazyConstruct(U&&... u)
       : create( [=]() -> T* { return new T(u...); } ) 
   {}
   T& get() {
      if(!data) data.reset( data.reset( create() ) );
      return *data;
   }
private:
   std::unique_ptr<T> data;
   std::function<auto()->T*> create;
};
模板
结构懒散构造{
//接受任意数量的参数,
//之后将用于构造T
模板
懒散构造(U&&…U)
:create([=]()->T*{返回新的T(u..;})
{}
T&get(){
如果(!data)data.reset(data.reset(create());
返回*数据;
}
私人:
std::唯一的ptr数据;
std::function*>create;
};
免责声明:编译器的手不能触摸代码


注意:虽然我现在无法确切地说出这个想法的错误(已经很晚了),但不知何故,懒惰的创作闻起来并不正确。我怀疑是过早的优化。

这里有一个复杂的方法来做你想做的事情。基本思想是让
LazyConstruct
将参数包存储在
tuple
中,然后根据需要解压
tuple
以构造
T

template<class T, class... Args>
struct LazyConstruct {
   // accept any number of arguments, 
   // which would later be used to construct T
   template<class... U>
   LazyConstruct(U&&... u)
   : args(std::make_tuple(std::forward<U>(u)...))
   {
   }

   T& get() {
      if(!data) data = create(std::index_sequence_for<Args...>());
      return *data;
   }

   template<std::size_t... I>
   std::unique_ptr<T> create(std::index_sequence<I...>)
   {
      return std::unique_ptr<T>{new T(std::get<I>(args)...)};
   }

private:
   std::tuple<typename std::decay<Args>::type...> args;
   std::unique_ptr<T> data;
};


另一个基于的版本使用了
std::function
,因此
LazyConstruct
的类型不会根据
t
的构造函数签名而改变

template<class T>
struct LazyConstruct {
   template<class... Args>
   LazyConstruct(Args&&... args)
   : holder([this, args = std::make_tuple(std::forward<Args>(args)...)]() {
            return create(std::index_sequence_for<Args...>(), std::move(args));
       })
   {
   }

   T& get() {
      if(!data) data = holder();
      return *data;
   }

   template<std::size_t... I, class Tuple>
   std::unique_ptr<T> create(std::index_sequence<I...>, Tuple args)
   {
      return std::unique_ptr<T>{new T(std::get<I>(args)...)};
   }

private:
   std::function<std::unique_ptr<T>()> holder;
   std::unique_ptr<T> data;
};
模板
结构懒散构造{
模板
懒散构造(Args&&…Args)

:holder([this,args=std::make_tuple(std::forward

这里有一种复杂的方法来做你想做的事情。基本思想是让
LazyConstruct
将参数包存储在
tuple
中,然后根据需要解压
tuple
来构造
T

template<class T, class... Args>
struct LazyConstruct {
   // accept any number of arguments, 
   // which would later be used to construct T
   template<class... U>
   LazyConstruct(U&&... u)
   : args(std::make_tuple(std::forward<U>(u)...))
   {
   }

   T& get() {
      if(!data) data = create(std::index_sequence_for<Args...>());
      return *data;
   }

   template<std::size_t... I>
   std::unique_ptr<T> create(std::index_sequence<I...>)
   {
      return std::unique_ptr<T>{new T(std::get<I>(args)...)};
   }

private:
   std::tuple<typename std::decay<Args>::type...> args;
   std::unique_ptr<T> data;
};


另一个基于的版本使用了
std::function
,因此
LazyConstruct
的类型不会根据
t
的构造函数签名而改变

template<class T>
struct LazyConstruct {
   template<class... Args>
   LazyConstruct(Args&&... args)
   : holder([this, args = std::make_tuple(std::forward<Args>(args)...)]() {
            return create(std::index_sequence_for<Args...>(), std::move(args));
       })
   {
   }

   T& get() {
      if(!data) data = holder();
      return *data;
   }

   template<std::size_t... I, class Tuple>
   std::unique_ptr<T> create(std::index_sequence<I...>, Tuple args)
   {
      return std::unique_ptr<T>{new T(std::get<I>(args)...)};
   }

private:
   std::function<std::unique_ptr<T>()> holder;
   std::unique_ptr<T> data;
};
模板
结构懒散构造{
模板
懒散构造(Args&&…Args)

:holder([this,args=std::make_tuple(std::forward

根据前面的注释)。您希望延迟并捕获参数

编辑:通用解决方案,应在C++11中工作。警告:未测试。应用函数留作练习。有关可能的实现,请参阅:

template <class T>
struct make {
    template <class...Args>
    T operator()(Args &&... args) const {
        return T(std::forward<Args>(args)...);
  }
};


template <class T, class... Args>
struct object_builder {

    object_builder(Args... && args) :
        captured_args_(std::forward<Args>(args)...) {}

    T operator()() const {
        return apply(make<T>{},
                 captured_args_);
}

 private:
    std::tuple<Args...> captured_args_;
};


template <class T, class...Args>
object_builder<T, Args...> make_object_builder(Args &&...args) {
    return object_builder<T, Args...>(std::forward<Args>(args)...);
}

int main() {
    //Create builders with captured arguments
    auto scary_monster_builder = 
        make_object_builder<Monster>(scary, "big orc");
    auto easy_monster_builder = make_object_builder<Monster>(easy,
                                                         "small orc");

    //Instantiate objects with the captured arguments from before
    auto a_scary_monster = scary_monster_builder();
    auto an_easy_monster = easy_monster_builder();
}
模板
结构制造{
模板
T运算符()(参数&&…参数)常量{
返回T(标准:正向(参数)…);
}
};
模板
结构对象生成器{
对象生成器(参数…&&Args):
捕获的参数(std::forward(args)…{}
T运算符()()常量{
返回apply(使{},
捕获的参数(args);
}
私人:
std::捕获的元组参数;
};
模板
对象生成器生成对象生成器(Args&&…Args){
返回对象构建器(std::forward(args)…);
}
int main(){
//使用捕获的参数创建生成器
自动恐怖怪物构建器=
制造物体(可怕的“大兽人”);
auto easy\u monster\u builder=生成对象\u builder(easy,
“小兽人”);
//使用以前捕获的参数实例化对象
自动生成一个可怕的怪物=可怕的怪物构建器();
自动生成一个简单的怪物=简单的怪物构建器();
}

根据前面的注释。您希望延迟并捕获参数

编辑:通用解决方案,应在C++11中工作。警告:未测试。应用函数留作练习。有关可能的实现,请参阅:

template <class T>
struct make {
    template <class...Args>
    T operator()(Args &&... args) const {
        return T(std::forward<Args>(args)...);
  }
};


template <class T, class... Args>
struct object_builder {

    object_builder(Args... && args) :
        captured_args_(std::forward<Args>(args)...) {}

    T operator()() const {
        return apply(make<T>{},
                 captured_args_);
}

 private:
    std::tuple<Args...> captured_args_;
};


template <class T, class...Args>
object_builder<T, Args...> make_object_builder(Args &&...args) {
    return object_builder<T, Args...>(std::forward<Args>(args)...);
}

int main() {
    //Create builders with captured arguments
    auto scary_monster_builder = 
        make_object_builder<Monster>(scary, "big orc");
    auto easy_monster_builder = make_object_builder<Monster>(easy,
                                                         "small orc");

    //Instantiate objects with the captured arguments from before
    auto a_scary_monster = scary_monster_builder();
    auto an_easy_monster = easy_monster_builder();
}
模板
结构制造{
模板
T运算符()(参数&&…参数)常量{
返回T(标准:正向(参数)…);
}
};
模板
结构对象生成器{
对象生成器(参数…&&Args):
捕获的参数(std::forward(args)…{}
T运算符()()常量{
返回apply(使{},
捕获的参数(args);
}
私人:
std::捕获的元组参数;
};
模板
对象生成器生成对象生成器(Args&&…Args){
返回对象构建器(std::forward(args)…);
}
int main()