Учитывая следующий исходный код:
#include <memory>
#include <iostream>
using namespace std;
struct concept
{
virtual void perform() = 0;
};
struct model : concept, enable_shared_from_this<model>
{
void perform() override {
cout << "my pointer is " << shared_from_this().get() << endl;
}
};
int main(int argc, const char * argv[])
{
// shared_ptr<concept> concept_ptr = make_shared<model>();
shared_ptr<concept> concept_ptr { new model };
concept_ptr->perform();
return 0;
}
Компиляция под gcc
, этот код компилирует и связывает внутренний weak_ptr
с адресом model
.
В clang
код не будет компилироваться (сообщение об ошибке включено в конце)
Если вы замените инициализацию concept_ptr
на shared_ptr<concept> concept_ptr = make_shared<model>();
, она скомпилируется на обоих.
Что правильно?
изменить:
Моя версия clang - это та, которая поставляется с Xcode
:
$ clang --version
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix
edit2:
Просто хотел сказать спасибо всем за вклад.
Если вам интересно, причина, по которой я хочу сделать это, - это то, что я хочу непрозрачный интерфейс для реализации с семантикой shared-handle. Некоторые реализации (асинхронные) требуют, чтобы объекты обратного вызова гарантировали, что объект реализации все еще существует (утверждает shared_from_this
и weak_ptr::lock
). Другие реализации этого не требуют. Я хотел избегать обременения концепции (публичного интерфейса) базовым классом enable_shared_from_this<>
, поскольку эта реализация пар с интерфейсом - известное зло.
В большинстве случаев разумно использовать make_shared для создания объекта реализации. В более редких случаях, требующих настраиваемого деструктора, следующее выглядит переносимым:
auto concept_ptr = static_pointer_cast<concept>(shared_ptr<model> {
new model ,
[](model* self) {
// some_deletion_operation on self;
} });
Приложение: сообщение об ошибке на clang:
In file included from /Users/richardh/Documents/dev/Scratchpad/tryit/tryit/try2.cpp:1:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:4013:35: error: no viable overloaded '='
__e->__weak_this_ = *this;
~~~~~~~~~~~~~~~~~ ^ ~~~~~
...etc...