Std :: shared_ptr et les listes d'initialisation
Le std::shared_ptr constructeur n'est pas se comporter comme je m'y attendais:
#include <iostream>
#include <vector>
void func(std::vector<std::string> strings)
{
for (auto const& string : strings)
{
std::cout << string << '\n';
}
}
struct Func
{
Func(std::vector<std::string> strings)
{
for (auto& string : strings)
{
std::cout << string << '\n';
}
}
};
int main(int argc, const char * argv[])
{
func({"foo", "bar", "baz"});
Func({"foo", "bar", "baz"});
//auto ptr = std::make_shared<Func>({"foo", "bar", "baz"}); //won't compile.
//auto ptr = std::make_shared<Func>{"foo", "bar", "baz"}; //nor this.
return 0;
}
Je fais quelque chose de mal ou est le compilateur? Le compilateur est:
$ clang++ --version
Apple clang version 4.0 (tags/Apple/clang-421.0.57) (basé sur LLVM 3.1 svn)
edit: shared_ptr au lieu de make_shared.
Voici l'erreur:
make -k
clang++ -std=c++11 -stdlib=libc++ main.cc -o main
main.cc:28:18: error: no matching function for call to 'make_shared'
auto ptr = std::make_shared<Func>({"foo", "bar", "baz"});
^~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/c++/v1/memory:4621:1: note: candidate function not viable:
requires 0 arguments, but 1 was provided
make_shared(_Args&& ...__args)
^
1 error generated.
source d'informationauteur dpj
Vous devez vous connecter pour publier un commentaire.
Essayez ceci:
Clang n'est pas prêt d'en déduire le type de
{"foo", "bar", "baz"}
. Je ne suis pas sûr de savoir si c'est la façon dont la langue est censé fonctionner, ou si nous sommes à la recherche à un bug du compilateur.Le constructeur de
shared_ptr<T>
prend un pointeur de typeT*
comme argument, supposé point à un allouée dynamiquement des ressources (ou au moins quelque chose qui peut être libéré par le deleter). D'autre part,make_shared
la construction pour vous et prend les arguments du constructeur directement.Donc, soit vous dire ceci:
Ou, beaucoup mieux et plus efficacement:
La dernière forme se charge de la répartition et de la construction pour vous, et dans le processus crée une application plus efficace.
Vous pouvez bien sûr aussi dire
make_shared<Foo>(Foo('a', true, Blue))
mais cela ne ferait que créer une copie superflue (qui peut être élidée), et plus important encore, il crée inutile redondance. [Modifier] Pour initialiser votre vecteur, c'est peut-être la meilleure méthode:Le point important est, cependant, que
make_shared
effectue l'allocation dynamique pour vous, alors partagé ptr constructeur ne paset au lieu prend possession.Vous devez utiliser
make_shared
si vous souhaitez créer un nouvel objet, construit à partir de ces arguments, pointé par unshared_ptr
.shared_ptr<T>
est comme un pointeur versT
- il doit être construit avec un pointeur àT
pas unT
.Edit: le transfert Parfait est en fait pas du tout parfait lorsque l'initialiseur de listes sont impliqués (qui est la sucer). Ce n'est pas un bug du compilateur. Vous devrez créer une rvalue de type
Func
manuellement.