Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.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++ gcc 4.9递归lambda返回时出现内部编译器错误_C++_Gcc_C++14_Gcc4.9 - Fatal编程技术网

C++ gcc 4.9递归lambda返回时出现内部编译器错误

C++ gcc 4.9递归lambda返回时出现内部编译器错误,c++,gcc,c++14,gcc4.9,C++,Gcc,C++14,Gcc4.9,我有一小段代码,在ClangRepoHead(3.5)中编译得很好,但在GCC4.9RepoHead中编译得不好。虽然这看起来像是一个gcc bug,但在垃圾发布bugzilla之前,我想问你 这是有效的c++1y代码(在当前草稿状态下)-仅仅因为clang编译了它,所以它没有理由是正确的代码,并且 如果有人能复制这个错误 使用clang编译和运行的代码段如下: 然而使用 g++-4.9 -o main main.cpp -std=c++1y 给出上述内部编译器错误: 如果没有长转储,它将显

我有一小段代码,在ClangRepoHead(3.5)中编译得很好,但在GCC4.9RepoHead中编译得不好。虽然这看起来像是一个gcc bug,但在垃圾发布bugzilla之前,我想问你

  • 这是有效的c++1y代码(在当前草稿状态下)-仅仅因为clang编译了它,所以它没有理由是正确的代码,并且
  • 如果有人能复制这个错误
  • 使用clang编译和运行的代码段如下:

    然而使用

    g++-4.9 -o main main.cpp -std=c++1y
    
    给出上述内部编译器错误:

    如果没有长转储,它将显示:

    g++-4.9-o main.cpp-std=c++1y main.cpp:在“composer::operator()(Func&&,Funcs&&…):[with auto:2=float;Func=main(int,const char*)::;Funcs={main(int,const char*)::}]的实例化中: main.cpp:33:88:从此处开始需要

    main.cpp:19:41:内部编译器错误:在cp/pt.c:1042处的检索_专门化中
    返回f(c(std::forward(fs)…(v));
    ^
    
    为了完整起见,这里是代码片段(完整的main.cpp)

    #包括
    #包括
    样板
    结构作曲家;
    样板
    结构编写器{
    自动运算符()(){
    返回[&](自动v){return v;};
    }
    };
    样板
    结构编写器{
    自动运算符(){
    作曲家c;
    返回[&](自动v){
    返回f(c(std::forward(fs)…(v));
    };
    }
    };
    样板
    自动合成(函数和…函数){
    作曲家c;
    返回c(std::forward(fs)…);
    }
    int main(int argc,char const*argv[]{
    浮球v=3.5f;
    auto t=compose([](auto v){return v>=3;},[](auto v){return int(v-0.5);})(v);
    
    std::cout您的代码在C++1y中无效,至少在执行时无效

    通过引用捕获变量,然后退出定义变量的范围,然后调用使用所述变量的lambda

    现在,从未使用
    c
    的状态,但是
    operator()
    调用仍然是UB

    类似地,虽然您的引用指向的是超出当前范围的数据,但不能保证捕获的是原始变量,而不是本地引用。实现本地捕获的一种方法是捕获指向本地堆栈帧的指针,并通过编译时静态偏移量从所述堆栈帧访问变量:如前所述如果使用堆栈帧,这样的读取将产生垃圾。(这将把
    [&]
    lambda的大小减少到一个指针,这是一个非常好的优化!在某些机器上,通过指针的偏移量访问数据非常快。)

    一般来说,如果您的闭包(或其副本)将超过当前范围,则不要通过引用捕获(尤其是通过全局引用)。在
    return
    语句上通过全局引用捕获应该会产生警告

    在C++1y中,您可以通过-
    move
    或-
    forward
    进行捕获

    如果没有C++1y编译器,下面是一个尝试:

    #include <iostream>
    auto compose() {
      return [](auto&& x) { return std::forward<decltype(x)>(x); };
    }
    
    template<typename F>
    auto compose( F&& f ) {
      return std::forward<F>(f);
    }
    
    template<typename F1, typename F2>
    auto compose( F1&& f1, F2&& f2 ) {
      return [lhs = std::forward<F1>(f1), rhs = std::forward<F2>(f2)]( auto&& x ) {
        return lhs( rhs( std::forward<decltype(x)>(x) ) );
      };
    }
    
    template<typename F0, typename... Fs>
    auto compose( F0&& f0, Fs&&... fs ) {
      static_assert( sizeof...(Fs) > 1, "other overrides should have handled this case!  What went wrong?" );
      return compose(
        std::forward<F0>(f0),
        compose(
          std::forward<Fs>(fs)...
        )
      );
    }
    
    int main() {
      auto a = compose( [](bool b){return !b;}, [](double d){ return d<3.0; } );
      std::cout << a(2.0) << "," << a(3.0) << "\n";
      return 0;
    }
    
    #包括
    自动合成(){
    return[](auto&&x){return std::forward(x);};
    }
    样板
    自动合成(F&&F){
    返回std::向前(f);
    }
    样板
    自动合成(F1&&F1,F2&&F2){
    返回[lhs=std::forward(f1),rhs=std::forward(f2)](自动和x){
    返回左侧(右侧(std::forward(x));
    };
    }
    样板
    自动合成(F0&&F0,Fs&&Fs){
    static_assert(sizeof…(Fs)>1,“其他覆盖应该已经处理了这种情况!出了什么问题?”);
    返回撰写(
    标准:正向(f0),
    谱写(
    标准::转发(fs)。。。
    )
    );
    }
    int main(){
    
    auto a=compose([](bool b){return!b;},[](double d){return d您的代码在C++1y中无效,至少在执行时无效

    通过引用捕获变量,然后退出定义变量的范围,然后调用使用所述变量的lambda

    现在,从未使用
    c
    的状态,但是
    operator()
    调用仍然是UB

    类似地,虽然您的引用指向的是超出当前范围的数据,但不能保证捕获的是原始变量,而不是本地引用。实现本地捕获的一种方法是捕获指向本地堆栈帧的指针,并通过编译时静态偏移量从所述堆栈帧访问变量:如前所述如果使用堆栈帧,这样的读取将产生垃圾。(这将把
    [&]
    lambda的大小减少到一个指针,这是一个非常好的优化!在某些机器上,通过指针的偏移量访问数据非常快。)

    一般来说,如果您的闭包(或其副本)将超过当前范围,则不要通过引用捕获(尤其是通过全局引用)。在
    return
    语句上通过全局引用捕获应该会产生警告

    在C++1y中,您可以通过-
    move
    或-
    forward
    进行捕获

    如果没有C++1y编译器,下面是一个尝试:

    #include <iostream>
    auto compose() {
      return [](auto&& x) { return std::forward<decltype(x)>(x); };
    }
    
    template<typename F>
    auto compose( F&& f ) {
      return std::forward<F>(f);
    }
    
    template<typename F1, typename F2>
    auto compose( F1&& f1, F2&& f2 ) {
      return [lhs = std::forward<F1>(f1), rhs = std::forward<F2>(f2)]( auto&& x ) {
        return lhs( rhs( std::forward<decltype(x)>(x) ) );
      };
    }
    
    template<typename F0, typename... Fs>
    auto compose( F0&& f0, Fs&&... fs ) {
      static_assert( sizeof...(Fs) > 1, "other overrides should have handled this case!  What went wrong?" );
      return compose(
        std::forward<F0>(f0),
        compose(
          std::forward<Fs>(fs)...
        )
      );
    }
    
    int main() {
      auto a = compose( [](bool b){return !b;}, [](double d){ return d<3.0; } );
      std::cout << a(2.0) << "," << a(3.0) << "\n";
      return 0;
    }
    
    #包括
    自动合成(){
    return[](auto&&x){return std::forward(x);};
    }
    样板
    自动合成(F&&F){
    返回std::向前(f);
    }
    样板
    自动合成(F1&&F1,F2&&F2){
    返回[lhs=std::forward(f1),rhs=std::forward(f2)](自动和x){
    返回左侧(右侧(std::forward(x));
    };
    }
    样板
    自动合成(F0&&F0,Fs&&Fs){
    static_assert(sizeof…(Fs)>1,“其他覆盖应该已经处理了这种情况!出了什么问题?”);
    返回撰写(
    标准:正向(f0),
    谱写(
    标准::转发(fs)。。。
    )
    );
    }
    int main(){
    
    自动a=compose([](bool b){return!b;},[](double d){return d
    如果有人可以复制这个bug。
    你检查了吗?很遗憾,我没有找到与这个问题相关的bug,没有。我可以在
    gcc版本4.9.0 20131223(实验性)(gcc)
    好的,这是一个问题的答案,谢谢。Indep
    #include <iostream>
    auto compose() {
      return [](auto&& x) { return std::forward<decltype(x)>(x); };
    }
    
    template<typename F>
    auto compose( F&& f ) {
      return std::forward<F>(f);
    }
    
    template<typename F1, typename F2>
    auto compose( F1&& f1, F2&& f2 ) {
      return [lhs = std::forward<F1>(f1), rhs = std::forward<F2>(f2)]( auto&& x ) {
        return lhs( rhs( std::forward<decltype(x)>(x) ) );
      };
    }
    
    template<typename F0, typename... Fs>
    auto compose( F0&& f0, Fs&&... fs ) {
      static_assert( sizeof...(Fs) > 1, "other overrides should have handled this case!  What went wrong?" );
      return compose(
        std::forward<F0>(f0),
        compose(
          std::forward<Fs>(fs)...
        )
      );
    }
    
    int main() {
      auto a = compose( [](bool b){return !b;}, [](double d){ return d<3.0; } );
      std::cout << a(2.0) << "," << a(3.0) << "\n";
      return 0;
    }