C++ C++;:用c+增强融合折叠+;14通用兰博达斯

C++ C++;:用c+增强融合折叠+;14通用兰博达斯,c++,boost,lambda,c++14,auto,C++,Boost,Lambda,C++14,Auto,我正在尝试将一个通用lambda函数传递给boost::fusion::fold函数,以便迭代boost::fusion::vector的所有元素。我的目标是从向量中的每个元素调用一个非常量成员函数。问题在于,即使向量包含非常量值,由泛型lambda导出的类型也是常量引用。这导致我的gcc-4.9.0编译器(使用CygWin)抱怨我正在丢弃const限定符 #include <iostream> #inc

我正在尝试将一个通用lambda函数传递给boost::fusion::fold函数,以便迭代boost::fusion::vector的所有元素。我的目标是从向量中的每个元素调用一个非常量成员函数。问题在于,即使向量包含非常量值,由泛型lambda导出的类型也是常量引用。这导致我的gcc-4.9.0编译器(使用CygWin)抱怨我正在丢弃const限定符

#include <iostream>                                        
#include <boost/fusion/include/vector.hpp>                             
#include <boost/fusion/include/fold.hpp>                               
#include <boost/fusion/include/for_each.hpp>                               

class Silly {                                              

public:                                                
  Silly(int x)                                             
    : x_(x){}                                              

  int increment(int i) {                                       
    return x_ += i;                                        
  }                                                                                                                                        

private:                                               
  int x_;                                              
};                                                 

using my_type = boost::fusion::vector<Silly, Silly>;                           


int main() {                                               
  my_type my_vector(1, 2);                                     
  boost::fusion::fold(my_vector, 0, [](int i, auto& x){return x.increment(i);}); //error: passing 'const Silly' as 'this' argument of 'int Silly::increment(int)' discards qualifiers                                      
}                                                                                              
#包括
#包括
#包括
#包括
类{
公众:
傻瓜(int x)
:x_ux(x){}
整数增量(整数i){
返回x_+=i;
}                                                                                                                                        
私人:
int x_2;;
};                                                 
使用my_type=boost::fusion::vector;
int main(){
my_类型my_向量(1,2);
boost::fusion::fold(my_vector,0,[](int i,auto&x){return x.increment(i);})//错误:将'const Silly'作为'int Silly::increment(int)'的'this'参数传递会丢弃限定符
}                                                                                              
现在,如果我传递的不是lambda,而是下面的函子,那么程序可以干净地编译

struct functor {

  template <class X>
  int operator()(int i, X& x) {
  return x.increment(i);
 }
};
结构函子{ 模板 int运算符()(int i、X和X){ 返回x.增量(i); } };
这是boost::fusion bug还是我遗漏了什么?提前谢谢

存在多个
boost::fusion::fold
重载。发件人:


附带说明:如a中所述,以下函数对象类型也会出现硬错误:

struct functor {
  int operator()(int i, Silly& x) {
  return x.increment(i);
 }
};
但失败的原因不同: 同样,所有
fold
重载都需要用各自的类型实例化::fold类模板的
结果。但是,该类模板不会在即时上下文中产生替换错误:如果传递的函数不能用传递的参数类型调用,则会发生硬错误

由于不能使用
int
Silly const&
类型的参数调用
int(int,Silly&)
类型的函数,因此会发生硬错误

在将apply操作符作为模板编写时(如C++14返回类型推断的示例中),可以为类型为
Silly const&
的第二个参数实例化
操作符()
模板的声明(
X
将被推断为
Silly const
)。但是,无法实例化函数定义,因为这将导致与OP中相同的错误:
Silly::increment
需要非常量
Silly
对象


但是,如果没有返回类型推断,则只有在重载解析之后才会实例化函数的定义。因此,这不会导致替换失败。

这与返回类型扣减有关。它不在直接上下文中生成替换失败。证明:显式指定lambda的返回类型,它就可以正常工作。@dyp~:谢谢,可以了。如果你给我一个答案,我会接受的:)你能不能再详细说明一下它到底在哪里失败了?再次感谢,这是一个相当模糊的问题。如果boost.fusion最初是为>=C++11编写的,那么我们可能没有这个问题,因为可能会有一个
折叠
模板获取转发引用。如果显式提供了返回类型,那么它就可以工作,因为返回类型可以单独从声明中确定,因此编译器不允许隐式实例化模板
操作符()
的定义。相反,如果其
运算符()
的返回类型设置为
auto
@T.C,则问题中的
结构函子将中断。啊,是的,我在OP的注释中提到过,但忘了在这里添加它。添加了它。这里可能也有一个bug。给定
struct函子{int operator()(inti,styl&x)const;}常量接受重载实际上会导致一个硬错误,这是很愚蠢的。@T.C.罪魁祸首是
boost::fusion::result\u of::fold
。它使用继承,将替换失败转移到中介上下文中。示例:使用模板时,即使对于常量参数也可以实例化声明,因此替换不会失败。
struct functor {
  template <class X>
  auto operator()(int i, X& x) {
  return x.increment(i);
 }
};
struct functor {
  int operator()(int i, Silly& x) {
  return x.increment(i);
 }
};