Aucun type nommé "unique" dans l'espace de noms 'std' lors de la compilation sous LLVM/Clang
Je suis attraper une erreur de compilation lors de la tentative d'utilisation unique_ptr
sur les plateformes Apple avec -std=c++11
:
$ make
c++ -std=c++11 -DNDEBUG -g2 -O3 -fPIC -march=native -Wall -Wextra -pipe -c 3way.cpp
In file included ...
./smartptr.h:23:27: error: no type named 'unique_ptr' in namespace 'std'
using auto_ptr = std::unique_ptr<T>;
~~~~~^
./smartptr.h:23:37: error: expected ';' after alias declaration
using auto_ptr = std::unique_ptr<T>;
Selon Marshall Clow, qui je considère comme un expert sur le C++ de la Bibliothèque Standard avec Clang et Apple:
Rapport technique no 1 (TR1) est un ensemble de bibliothèque ajouts du C++03
standard. Représentant le fait qu'ils ne faisaient pas partie de la
"officiel" de la norme, ils ont été placés dans l'espace de noms std::tr1.En c++11, ils sont officiellement partie de la norme, et de vivre dans la
l'espace de noms std, tout comme vecteur et de la chaîne. Les fichiers d'en-no
plus vivre dans le "tr1" le dossier, soit.
La vente à emporter:
- Apple et C++03 = utiliser TR1 espace de noms
- Apple et C++11 = utiliser l'espace de noms STD
- Utilisation
LIBCPP_VERSION
pour détecterlibc++
Maintenant, voici ce que j'ai dans smartptr.h
:
#include <memory>
//Manage auto_ptr warnings and deprecation in C++11
//Microsoft added template aliases to VS2015
#if (__cplusplus >= 201103L) || (_MSC_VER >= 1900)
template<typename T>
using auto_ptr = std::unique_ptr<T>;
#else
using std::auto_ptr;
#endif //C++11
Je pense que la dernière chose à vérifier est les __APPLE__
définir, et c'est ici:
$ c++ -x c++ -dM -E - < /dev/null | grep -i apple
#define __APPLE_CC__ 6000
#define __APPLE__ 1
#define __VERSION__ "4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)"
#define __apple_build_version__ 5030040
Pourquoi reçois-je un error: no type named 'unique_ptr' in namespace 'std'
lors de l'utilisation de -std=c++11
?
Je pense que ce sont les quatre cas de test. Il tente d'exercer les quatre configurations de la croix de produits de: {C++03,C++11} x {libc++,libstdc++}.
- c++ -c test-clapple.cxx
- OK
- c++ -stdlib=libc++ -c test-clapple.cxx
- OK
- c++ -std=c++11 -c test-clapple.cxx
- ÉCHOUER
- c++ -std=c++11 -stdlib=libc++ -c test-clapple.cxx
- OK
Ici est le pilote d'essai. Assurez-vous de le tester sur OS X de sorte que vous obtenez le plein des effets de la TR1 espace de noms en 2015.
$ cat test-clapple.cxx
//c++ -c test-clapple.cxx
//c++ -stdlib=libc++ -c test-clapple.cxx
//c++ -std=c++11 -c test-clapple.cxx
//c++ -std=c++11 -stdlib=libc++ -c test-clapple.cxx
#include <memory>
//Manage auto_ptr warnings and deprecation in C++11
#if (__cplusplus >= 201103L) || (_MSC_VER >= 1900)
template<typename T>
using auto_ptr = std::unique_ptr<T>;
#else
using std::auto_ptr;
#endif //C++11
int main(int argc, char* argv[])
{
return argc;
}
- Il n'y a pas de
std::tr1::auto_ptr
sur toute plate-forme jamais que je suis au courant. - Oups... j'ai réalisé que c'était une erreur, et il a été changé. Mais j'ai seulement changé dans le cas de test que j'ai posté. Permettez-moi de le mettre à jour.
Vous devez vous connecter pour publier un commentaire.
Non, ils n'ont pas. Ils vous a dit de faire quelque chose de similaire si vous souhaitez utiliser
shared_ptr
, parce que pour le C++03<tr1/memory>
définitstd::tr1::shared_ptr
et pour le C++11<memory>
définitstd::shared_ptr
.Mais vous ne l'utilisez pas
shared_ptr
. Si vous souhaitez utiliserauto_ptr
alors c'est justestd::auto_ptr
, partout, ce qui est toujours défini dans<memory>
.Je pense que vous avez mal compris Marshall commentaire et vous êtes de compliquer à l'excès des choses. Ce que vous avez cité ('En c++11, ils sont officiellement partie de la norme, et de vivre dans l'espace de noms std, tout comme vecteur et de la chaîne. Les fichiers d'en-ne vivons plus dans le "tr1" le dossier, soit.') n'est pas Apple ou spécifiques à un Bruit spécifique, il s'applique à tous les compilateurs. Mais depuis
auto_ptr
n'a jamais fait partie de TR1 et jamais dans<tr1/memory>
il est sans importance que le contenu de TR1 sont maintenant dans l'espace de nomsstd
, parce que ce que vous essayez d'utiliser n'a jamais été inclus dans TR1.Vous ne devriez pas utiliser TR1 à tous les ici.
Cela devrait être correct pour les compilateurs modernes, mais ne fonctionne pas sur la bête de configuration fourni avec XCode, qui est une version moderne de Clang qui prend en charge le C++11 et de la libstdc++ GCC 4.2, qui est près de dix ans et ne prend pas en charge
unique_ptr
.À faire face avec la valeur par défaut OS X toolchain cela fonctionne:
Cela fonctionne en utilisant la présence de
<forward_list>
comme un indicateur de savoir si la bibliothèque standard clang est à l'aide de supportsstd::unique_ptr
.Si clang est à l'aide de la libc++ dans sa bibliothèque standard, puis toutes les versions de soutenir
unique_ptr
et également fournir<forward_list>
, de sorte que le test passe.Si clang est à l'aide de libstdc++ puis si
unique_ptr
est pris en charge dépend de la libstdc++ version.unique_ptr
a été ajouté à la bibliothèque libstdc++ GCC 4.3, qui est la même version qui a ajouté<forward_list>
, de sorte que si l'en-tête est disponible puisunique_ptr
sera trop. Si vous utilisez clang avec l'ancienne libstdc++ qui est livré avec la Pomme toolchains (à partir de GCC 4.2) puisunique_ptr
n'est pas pris en charge, mais ce n'est<forward_list>
, si le test échoue et que vous utilisezauto_ptr
à la place.Qui devrait fonctionner pour tout le GCC/libstdc++, Clang/libc++ ou Clang/libstdc++ combinaison trouvé dans la nature. Je ne sais pas ce qui est nécessaire pour VC++/Dinkumware et Clang/Dinkumware, de votre réponse, ça ressemble peut-être vous serait-il suffit de changer la condition première:
error: no type named 'unique_ptr' in namespace 'std'
lors de la compilation avec-std=c++11
et sans-stdlib=libc++
en vertu d'Apple Llvm (3.4 SVN) et de LLVM Clang (3.6).__cplusplus == 201103L
lorsque vous utilisez-std=c++11
le std::lib n'ont pas de C++11. Donc, vous pourriez avoir besoin de vérifier le std::lib utilisée, mais vous ne voulez pas tout ce qui a trait TR1.-stdlib=libc++
, LLVM metunique_ptr
dansstd::
, et passtd::tr1
.unique_ptr
n'a jamais fait partie de TR1. Aucun compilateur n'a jamais mis enstd::tr1
. Comme je l'ai dit ci-dessus, si vous essayez d'utiliser le commutateur entreauto_ptr
etunique_ptr
puis TR1 est complètement hors de propos, et vous ne devriez pas faire quoi que ce soit avecstd::tr1
ou tout<tr1/xxx>
en-tête.c++ -std=c++11 -c <file>
ne parvient pas à compiler, car il prétenderror: no type named 'unique_ptr' in namespace 'std'
. C'est exactement ce que vous me dites de faire.unique_ptr
était de nouveau en C++11. Il n'était pas en C++03, et il n'était pas dans TR1. Si vous utilisez une version de libstdc++ à partir de 2007, alors vous n'allez pas à obtenir de C++11 caractéristiques, même si vous utilisez-std=c++11
sur la ligne de commande, en raison de la nature linéaire du temps. Remarque la dernière phrase, j'ai ajouté à la réponse ci-dessus, il ya une heure.