Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.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+中模拟lambda的复制分配运算符+;_C++_C++11_Lambda - Fatal编程技术网

C++ 在C+中模拟lambda的复制分配运算符+;

C++ 在C+中模拟lambda的复制分配运算符+;,c++,c++11,lambda,C++,C++11,Lambda,这个问题有两部分 第一,有人解释了C++对LAMBDAS的复制赋值操作符禁用的原理吗?如果要允许复制构造函数,为什么不允许复制赋值操作符 其次,在不强迫人们编写C++03风格的functor或使用std::function(我处理的函数很小,我希望编译器尽可能内联它们)的情况下,如何最好地克服这一限制 背景: 我正在尝试在中实现类似平面映射的操作,类似于Scala或其他函数式语言中的平面映射。因此,我需要创建一个迭代器来迭代迭代器列表。每次取消引用平面映射迭代器时,都会执行与内部迭代器关联的la

这个问题有两部分


第一,有人解释了C++对LAMBDAS的复制赋值操作符禁用的原理吗?如果要允许复制构造函数,为什么不允许复制赋值操作符

其次,在不强迫人们编写C++03风格的functor或使用std::function(我处理的函数很小,我希望编译器尽可能内联它们)的情况下,如何最好地克服这一限制

背景: 我正在尝试在中实现类似平面映射的操作,类似于Scala或其他函数式语言中的平面映射。因此,我需要创建一个迭代器来迭代迭代器列表。每次取消引用平面映射迭代器时,都会执行与内部迭代器关联的lambda。每次内部迭代器到达末尾时,外部迭代器需要切换内部迭代器。由于内部迭代器包含lambda,因此没有复制赋值运算符,因此无法切换它。从技术上讲,我可以使用动态分配解决这个问题,因此我总是调用复制构造函数,但这似乎不是正确的方法。以下是可能有助于突出问题的代码片段:

template <typename Iter>
class flat_map_iterator {
public:
  flat_map_iterator& operator++() {
    ++it_inner_;
    if (it_inner_ == (*it_outer_).end()) {
      ++it_outer_;
      // ERROR: cannot be assigned because its copy assignment operator is implicitly deleted
      it_inner_ = (*it_outer_).begin();
    }
    return *this;
  }
private:
  Iter it_outer_; 
  typename Iter::value_type::iterator it_inner_;
};
模板
类平面映射迭代器{
公众:
平面映射迭代器和运算符++(){
++它是内在的;
if(it_内部==(*it_外部)。end()){
++它是外部的;
//错误:无法分配,因为其复制分配运算符已被隐式删除
it_内部=(*it_外部)。开始();
}
归还*这个;
}
私人:
国际热核实验堆;
typename Iter::value\u type::iterator it\u internal\u;
};
编辑

谢谢你的快速回复。下面是一个用例示例:

 int res = ftl::range(1, 4).map([](int a){
     return ftl::range(a, 4).map([a](int b){
         return std::make_tuple(a, b);
     });
 })
 .flat_map([](std::tuple<int, int> x){ return std::get<0>(x) * std::get<1>(x); })
 .sum();

 assert(res, 25);
intres=ftl::range(1,4).map([](inta){
返回ftl::范围(a,4).map([a](intb){
返回std::make_tuple(a,b);
});
})
.flat_映射([](std::tuple x){return std::get(x)*std::get(x);})
.sum();
断言(第25条);

ftl::range(begin,end)
函数返回范围内的惰性迭代器
并非是C++对Labbda本身的复制赋值操作符禁用,而是将lambda对象中的默认成员保存为const,然后赋值运算符基本上不做任何分配给它们,因此它不生成。如果您希望lambdas不将成员保持为const,则使用<代码>…(…)可变{…}
语法

另一件事是,我不完全确定分配lambda会带来什么。我的意思是,如果要重用lambda类型(和功能)简单地将其绑定到不同的变量,您已经在使用很好的lambda捕获语法,还可以将其作为普通函数对象。将一种lambda类型分配给另一种lambda是不可能的。这意味着您不能在按值保存lambda本身时提供不同的lambda实现

如果这仍然是您想要的,我认为动态分配(例如使用
unique\u ptr
)是公平的

如果您真的想避免它,您可以手动销毁并重新构造lambda,如下所示:

#include <iostream>

template <class T>
struct LambdaContainer {
    LambdaContainer(const T& lambda)
        : lambda{lambda} {}

    void resetLambda(const T& lambda) {
        this->lambda.~T();
        new (&this->lambda) T{lambda};
    }

    T lambda;
};

int main()
{
    int i = 1;

    auto l = [=]() {
        std::cout << i;
    };

    using LT = decltype(l);

    LambdaContainer<LT> lc{l};

    lc.resetLambda(l);
}
#包括
模板
结构LambdaContainer{
lambda容器(常数T和lambda)
:lambda{lambda}{}
无效重置λ(常数T和λ){
这个->lambda.~T();
新建(&this->lambda)T{lambda};
}
T lambda;
};
int main()
{
int i=1;
自动l=[=](){

std::cout请发布一个,包括带有lambda的使用代码“如果您要允许复制构造函数,为什么不允许复制赋值运算符”.Lambda倾向于存储引用。我不认为没有一些技巧就可以复制并分配存储在对象中的引用…如果您真的不想使用动态分配,请使用optional并每次使用正确的it\u inner\u重新构造它(而不是复制分配它).Assignment无论如何都会禁止内联。@W.F.没有考虑lambda存储引用。虽然这似乎应该取决于lambda的参数?这看起来是一个很好的解决方案。实现了它,看起来它可以编译。需要测试它。我不知道默认情况下成员存储为const,这就清楚了为什么复制为签名不起作用。不是我真的想重新分配lambda,而是我希望迭代器包含lambda。很好的lambda语法使创建这些迭代器更容易。我也需要这样做。我想要一个std::function的无堆版本。
可变
不会使数据成员保持常量;它使调用运算符const,因此它无法修改它们。