Kyl*_*and 12 c++ lambda inheritance templates c++14
模板化的类可以this在lambda中捕获自己的指针:
template <typename T>
class Foo {
public:
void foo(void) {}
auto getCallableFoo(void) {
return [this]() { this->foo(); };
}
};
Run Code Online (Sandbox Code Playgroud)
Foo可以使用以下代码测试此示例和所有其他示例:
int main()
{
Foo<int> f;
auto callable = f.getCallableFoo();
callable();
}
Run Code Online (Sandbox Code Playgroud)
但是,如果使用init-capture,则不再适用于GCC:
auto getCallableFoo(void) {
return [ptr = this]() { ptr->foo(); };
}
Run Code Online (Sandbox Code Playgroud)
错误消息(来自GCC 5.1):
error: ‘Foo<T>::getCallableFoo()::<lambda()>::__ptr’ has incomplete type
Run Code Online (Sandbox Code Playgroud)
Clang 3.7似乎编译并运行此代码而没有错误.(我实际上是在使用3.7之前从源代码编译的版本,但我不认为从那时起它已经破坏了.)
初始捕获应该像赋值一样auto,但是下面的代码似乎在GCC中没有错误地工作:
// New method in Foo:
auto getPtr(void) {
return this;
}
// Usage:
auto ptr = f.getPtr();
ptr->foo();
Run Code Online (Sandbox Code Playgroud)
那么为什么ptr价值不能this在GCC中捕获?这是一个错误吗?
另一个考虑因素是,根据CppReference,this它被视为与每个其他捕获列表类型的单独的语法案例.因此,这可能是为什么海湾合作委员会以不同方式处理这些案件的一个暗示.但是我不清楚对这个特殊情况做了什么(如果有的话)特殊处理,或者为什么它是一个特殊情况.
编辑:看来这确实有效:
return [ptr = static_cast<decltype(this)>(this)]() { ptr->foo(); };
Run Code Online (Sandbox Code Playgroud)
这是没有意义的我,因为decltype(不同于auto)推断正是它的参数的类型,所以static_cast不应该实际上是影响任何东西.
编辑2,3,4:这是我用两个编译器尝试过的完整表达式列表,其中的注释表明哪些编译器接受每个表达式:
[this]() { this->foo(); }; // Both: work
[ptr = this]() { ptr->foo(); }; // GCC fails
[ptr = static_cast<decltype(this)>(this)]() { ptr->foo(); }; // Both: works (!!!)
[ptr(this)]() { ptr->foo(); }; // GCC fails
[ptr{this}]() { ptr->foo(); }; // GCC works (!!!!!!!!), Clang doesn't work (infers initializer list)
[ptr = {this}]() { ptr->foo(); }; // Both: fail (infers initializer list)
[ptr = &*this]() { ptr->foo(); }; // Both: work
[ptr = &*(this)]() { ptr->foo(); }; // Both: work
Run Code Online (Sandbox Code Playgroud)
因为[ptr{this}],我的Clang版本(预发布3.7版)警告说,解释会改变; 目前它推断出初始化列表,但可能后来的版本将(或已经)this 根据autoN3922 的新规则推断出类型.
让海湾合作委员会允许[ptr{this}]但不是令我感到震惊[ptr(this)].我对此没有任何解释.
| 归档时间: |
|
| 查看次数: |
263 次 |
| 最近记录: |