C++11 没有名为'的类型;独特的ptr';在命名空间中';std&x27;在LLVM/Clang下编译时

C++11 没有名为'的类型;独特的ptr';在命名空间中';std&x27;在LLVM/Clang下编译时,c++11,c-preprocessor,unique-ptr,llvm-clang,c++03,C++11,C Preprocessor,Unique Ptr,Llvm Clang,C++03,在使用-std=c++11的Apple平台上尝试使用unique\ptr时,我发现一个编译错误: $ 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_p

在使用
-std=c++11
的Apple平台上尝试使用
unique\ptr
时,我发现一个编译错误:

$ 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>;
我想最后要检查的是
\uuuu APPLE\uuuu
定义,这里是:

$ 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
CFE开发人员特别告诉我使用该代码

不,他们没有。他们告诉你,如果你想使用
shared\u ptr
,也要做类似的事情,因为对于C++03
定义
std::tr1::shared\u ptr
,对于C++11
定义
std::shared\u ptr

但是您没有使用
共享\u ptr
。如果您想使用
auto_ptr
,那么它就是
std::auto_ptr
,无处不在,它总是在
中定义的

我认为你误解了马歇尔的评论,你把事情搞得太复杂了。您引用的('在c++11中,它们是标准的正式组成部分,位于名称空间std中,就像vector和string一样。include文件也不再位于“tr1”文件夹中。')不是特定于Apple或Clang的,它适用于所有编译器。但是由于
auto\u ptr
从来都不是TR1的一部分,也从来没有在
中,因此TR1的内容现在在名称空间
std
中是无关紧要的,因为您尝试使用的内容从未包含在TR1中

您不应该在此处使用TR1

# include <memory>

// Manage auto_ptr warnings and deprecation in C++11
#if (__cplusplus >= 201103L)
template<typename T>
using auto_ptr = std::unique_ptr<T>;
#else
using std::auto_ptr;
#endif // C++11
这是通过使用
作为标准库clang是否使用supports
std::unique\u ptr
的指示器来实现的

如果clang使用libc++作为其标准库,那么所有版本都支持
unique\u ptr
,并提供
,因此测试通过

如果clang正在使用libstdc++,那么是否支持
unique\u ptr
,取决于libstdc++版本unique\u ptr,该版本与添加的
版本相同,因此如果该头可用,则
unique\u ptr
也将可用。如果您将clang与Apple工具链(来自GCC 4.2)附带的古老libstdc++一起使用,则不支持
unique\u ptr
,但
也不支持,因此测试失败,您使用
auto\u ptr

这应该适用于在野外发现的任何GCC/libstdc++、Clang/libc++或Clang/libstdc++组合。我不知道VC++/Dinkumware和Clang/Dinkumware需要什么,从您的回答来看,您可能会将第一个条件更改为:

#if __cplusplus >= 201103L || _MSC_VER >= 1600

在我所知道的任何平台上都没有
std::tr1::auto_ptr
。@Jonathan,我的坏。。。我意识到这是个错误,于是改变了。但我只是在发布的测试用例中更改了它。让我更新一下。你说得对,谢谢。收割台位置确实取决于TR1。也许这就是我陷入兔子洞的原因…我仍然得到了
错误:在使用
-std=c++11
和不使用
-stdlib=libc++
进行编译时,名称空间“std”中没有名为“unique”的类型。这是因为它使用了Mac OS X上提供的古老libstdc++,这是来自GCC 4.2,所以即使Clang支持C++,并且定义<代码>“yp+cPLUS PLUS=201103L< /Cord>”,当您使用<代码> -STD= C++ 11 时,STD::LIB没有任何C++ 11支持。因此,您可能需要检查正在使用的std::lib,但您仍然不希望任何与TR1相关的内容。因此,当使用
-stdlib=libc++
时,LLVM会将
唯一的ptr
放在
std:
中,而不是
std::TR1
。因为Mac OS X上古老的libstdc++不支持C++11。如上所述,这一条上面有四条评论
unique_ptr
在C++11中是新出现的。它不在C++03中,也不在TR1中。如果使用2007年的libstdc++版本,那么由于时间的线性性质,即使在命令行上使用
-std=C++11
,也无法获得C++11功能。请注意我在一小时前添加到上述答案的最后一句话。
# include <memory>

// Manage auto_ptr warnings and deprecation in C++11
#if (__cplusplus >= 201103L)
template<typename T>
using auto_ptr = std::unique_ptr<T>;
#else
using std::auto_ptr;
#endif // C++11
#include <memory>

#if __cplusplus >= 201103L
# ifdef __clang__
#  if __has_include(<forward_list>)
// either using libc++ or a libstdc++ that's new enough to have unique_ptr
#   define HAVE_UNIQUE_PTR 1
#  endif
# else // not clang, assume unique_ptr available
#  define HAVE_UNIQUE_PTR 1
# endif
#endif

#ifdef HAVE_UNIQUE_PTR
template<typename T> using auto_ptr = std::unique_ptr<T>;
#else
using std::auto_ptr;
#endif
#if __cplusplus >= 201103L || _MSC_VER >= 1600