7
votes

I have succeeded writing a class like this one, capturing this in a lambda defined as non-static attribute of said class:

#include <memory>
#include <iostream>
#include <functional>

struct S
{
  S()
  {
    std::cout << "S::S()[" << this << "]" << std::endl;
  }

  std::string y_{"hi mate"};
  int x_;
  std::function<void(int*)> del_{[this](int *ptr)
  {
    std::cout << "Deleting ptr[" << ptr << "] this[" << this << "] this->y_[" << this->y_ << "]" << std::endl;
  }};
  std::unique_ptr<decltype(x_), decltype(del_)> unique_{&x_, del_};
};

int main()
{
  S s;
}

This compiles and seems to run just fine.

However, with a templated class, it doesn't work anymore:

#include <memory>
#include <iostream>
#include <functional>

template <typename>
struct S
{
  S()
  {
    std::cout << "S::S()[" << this << "]" << std::endl;
  }

  std::string y_{"hi mate"};
  int x_;
  std::function<void(int*)> del_{[this](int *ptr)
  {
    std::cout << "Deleting ptr[" << ptr << "] this[" << this << "] this->y_[" << this->y_ << "]" << std::endl;
  }};
  std::unique_ptr<decltype(x_), decltype(del_)> unique_{&x_, del_};
};

int main()
{
  S<int> s;
}

$> g++ -std=c++1y custom_deleter_template.cpp
~/test custom_deleter_template.cpp: In instantiation of ‘struct S::’: custom_deleter_template.cpp:9:3: required from ‘S< >::S() [with = int]’ custom_deleter_template.cpp:24:10:
required from here custom_deleter_template.cpp:15:35: internal compiler error: in tsubst_copy, at cp/pt.c:12569
std::function del_{[this](int *ptr) ^ Please submit a full bug report, with preprocessed source if appropriate. See for instructions. Preprocessed source stored into /tmp/pyro/ccxfNspM.out file, please attach this to your bugreport.

Before filing a bugreport (which I can't do, they blocked account creation), is it normal that it does not compile, based on what the standard says?

Compiler is g++ (Ubuntu 4.9.2-0ubuntu1~14.04) 4.9.2, used flag -std=c++1y. Same thing happens with flag -std=c++11.

1
Internal compiler errors are always a bug. That should compile as it does in clang. - 0x499602D2
I can reproduce with GCC 4.9.2 on OS X. - Cornstalks
it does compile in clang :) . - pyro
It also compiles with a more recent g++5.0, so it might be a bug that has already been fixed. - dyp
@dyp : do you mind giving a link to get g++5.0 on linux please? The only mirror I checked had only up to 4.9.x versions. - pyro

1 Answers

0
votes

This is indeed a bug in GCC, which is already being tracked.

It seems to affect 4.8 and 4.9. As pointed out in the comments this particular example works fine for 4.7 and 5.0. You can see that for yourself here and play with the different versions of gcc.

However this reduced version of your code with no external dependency still crashes with 5.0:

template <typename>
struct S {
  int f{[this](){return 42;}()};
};

int main(){
    return S<int>{}.f; //  should return 42
}

I would suggest that you wait for the bug I referenced to be fixed before using your code, or switch to another compiler ;).