在模板化 class 与非模板化 class 内的 lambda 属性中捕获此内容
Capture this in lambda attribute inside a templated class vs not-templated class
我已经成功地编写了一个像这样的 class,在定义为所述 class 的非静态属性的 lambda 中捕获它:
#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;
}
编译后似乎 运行 就好了。
但是,使用模板 class,它不再起作用:
#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.
在提交错误报告之前(我做不到,他们阻止了帐户创建),根据标准所说,它不编译是正常的吗?
编译器是 g++ (Ubuntu 4.9.2-0ubuntu1~14.04) 4.9.2,使用标志 -std=c++1y。标志 -std=c++11.
也会发生同样的事情
这确实是GCC的一个bug,已经是being tracked。
好像影响4.8和4.9。正如评论中所指出的,这个特定示例适用于 4.7 和 5.0。您可以自己查看 here 并使用不同版本的 gcc。
然而,这个没有外部依赖的简化版代码在 5.0 中仍然会崩溃:
template <typename>
struct S {
int f{[this](){return 42;}()};
};
int main(){
return S<int>{}.f; // should return 42
}
我建议您在使用您的代码之前等待我提到的错误被修复,或者切换到另一个编译器 ;)。
我已经成功地编写了一个像这样的 class,在定义为所述 class 的非静态属性的 lambda 中捕获它:
#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;
}
编译后似乎 运行 就好了。
但是,使用模板 class,它不再起作用:
#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.
在提交错误报告之前(我做不到,他们阻止了帐户创建),根据标准所说,它不编译是正常的吗?
编译器是 g++ (Ubuntu 4.9.2-0ubuntu1~14.04) 4.9.2,使用标志 -std=c++1y。标志 -std=c++11.
也会发生同样的事情这确实是GCC的一个bug,已经是being tracked。
好像影响4.8和4.9。正如评论中所指出的,这个特定示例适用于 4.7 和 5.0。您可以自己查看 here 并使用不同版本的 gcc。
然而,这个没有外部依赖的简化版代码在 5.0 中仍然会崩溃:
template <typename>
struct S {
int f{[this](){return 42;}()};
};
int main(){
return S<int>{}.f; // should return 42
}
我建议您在使用您的代码之前等待我提到的错误被修复,或者切换到另一个编译器 ;)。