2013-05-08 2 views
0

У меня есть следующий код:Почему shared_ptr <T> ожидает конструктор копирования/перемещения в T?

#include <memory> 

using namespace std; 

template<typename U> class A; 

template<typename U> 
class B 
{ 
    private: 
     shared_ptr<const A<U>> _a; 
    public: 
     B (shared_ptr<const A<U>> __a) { 
      _a = __a; 
     } 
}; 

template<typename U> 
class A 
{ 
    public: 
     B<U> foo() const { 
      return { make_shared<const A<U>> (this) }; 
     } 
}; 

int 
main() 
{ 
    A<int> a; 
    B<int> b = a.foo(); 

    return 0; 
} 

G ++ 4.8.0 и Clang 3.3svn сообщают, что класс A не имеет копию или переместить конструктор. Для например, G ++ напечатать следующее сообщение:

/home/alessio/Programmi/GCC/include/c++/4.8.0/ext/new_allocator.h:120:4: error: no  matching function for call to ‘A<int>::A(const A<int>* const)’ 
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } 
^
/home/alessio/Programmi/GCC/include/c++/4.8.0/ext/new_allocator.h:120:4: note: candidates are: 
prova.cpp:19:7: note: constexpr A<int>::A() 
class A 
    ^
prova.cpp:19:7: note: candidate expects 0 arguments, 1 provided 
prova.cpp:19:7: note: constexpr A<int>::A(const A<int>&) 
prova.cpp:19:7: note: no known conversion for argument 1 from ‘const A<int>* const’ to ‘const A<int>&’ 
prova.cpp:19:7: note: constexpr A<int>::A(A<int>&&) 
prova.cpp:19:7: note: no known conversion for argument 1 from ‘const A<int>* const’ to ‘A<int>&&’ 

В чем причина?

+0

'A' не является классом. Это шаблон. –

ответ

0

Согласно документации, make_shared конструирует новый экземпляр данного типа муравей затем оборачивает его в shared_ptr. Вы пытаетесь построить новый экземпляр A с типом A *. Это конструктор shared_ptr, который принимает указатель в качестве аргумента, а не make_shared.

+0

Но как 'make_shared' создает новый экземпляр? Вы полагаете, что в классе 'A' есть частное поле' C c'; если в классе 'A' нет конструктора copy/move, как он создает новый экземпляр? –

+0

'make_shared' вызывает конструктор класса' A'. Конструктор выбирается в соответствии с параметрами 'make_shared' (конечно, объект должен быть конструктивным определенным образом). Если вы хотите создать «shared_ptr», указывающий на существующий объект с помощью частного (запрещенного) конструктора копирования, вы должны использовать конструктор 'shared_ptr' напрямую, например' shared_ptr > (this) '. Обратите внимание, что в вашем случае у вас все еще есть конструктор копии по умолчанию для класса 'A', поэтому вы можете написать' make_shared > (* this) ', создав таким образом копию. – Inspired

5

Вы должны сказать:

return { make_shared<const A<U>>(*this) }; 
//        ^^^ 
Смежные вопросы