類型考慮下面的代碼:Lambda表達式,共享指針和本
#include <memory>
#include <cassert>
struct S: std::enable_shared_from_this<S> {
protected:
S() = default;
int bar() { return 42; }
};
struct T: S {
static std::shared_ptr<T> create() {
return std::shared_ptr<T>(new T{});
}
auto foo() {
auto ptr = std::static_pointer_cast<T>(shared_from_this());
return [ptr](){ return ptr->bar(); };
}
private:
T() = default;
};
int main() {
std::shared_ptr<T> ptr = T::create();
auto lambda = ptr->foo();
assert(lambda() == 42);
}
以上代碼編譯。它不如果該方法foo
被修改,因爲它遵循:
auto foo() {
// In this case, there is no explicit cast
// The type of ptr is no longer std::shared_ptr<T>
// It is std::shared_ptr<S> instead
auto ptr = shared_from_this();
return [ptr](){ return ptr->bar(); };
}
在這種情況下,代碼不再編譯(既不與GCC也不與鐺)。
顯然,這將鑄造後編譯(這是我的第一個例子),但我預計bar
要到拉姆達可見,即使在這種情況下,它是在它的上下文訪問,並且接口的一部分也是S
。
,我懷疑這是由於5.1.5p8,特別是:
拉姆達表達的複合語句產生了函數體的函數調用操作符的[...],但[.. 。],確定這個的類型和值,複合語句被認爲是在lambda表達式的上下文中。
事實上,通過鐺返回的錯誤是很清楚:
main.cpp中:8:9:注意:只能類型的對象上訪問此構件
T
我的推導是否正確?
是否由於提到的段落,因此this
指針的確定類型的問題與共享指針之一不匹配?
事實上,shared_ptr
參與遊戲使我有點難以理解。
老實說,我希望這兩個例子都可以編譯,或者兩者都會失敗。
你的'static_pointer_cast'消失了。另外,'返回[ptr = shared_from_this()](){返回ptr->酒吧(); };'行爲不同? – ildjarn
'shared_from_this'爲'S'返回一個共享指針,它不再被轉換爲'T'的共享指針。所以實際上,第二個例子中'ptr'的類型是'std :: shared_ptr
'。你想讓我以更可讀的方式寫嗎? – skypjack[Works for me](http://melpon.org/wandbox/permlink/hl00GHSN4JZ1Qhi1)經過一些簡單的修改。 –