在 LLVM/Clang 下编译时,命名空间 'std' 中没有名为 'unique_ptr' 的类型
No type named 'unique_ptr' in namespace 'std' when compiling under LLVM/Clang
我在 Apple 平台上尝试使用 unique_ptr
时遇到编译错误 -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>;
根据 Marshall Clow 的说法,我认为他是 C++ Standard Library with Clang and Apple 方面的专家:
Technical Report #1 (TR1) was a set of library additions to the C++03
standard. Representing the fact that they were not part of the
"official" standard, they were placed in the namespace std::tr1.
In c++11, they are officially part of the standard, and live in the
namespace std, just like vector and string. The include files no
longer live in the "tr1" folder, either.
外卖:
- Apple 和 C++03 = 使用 TR1 命名空间
- Apple 和 C++11 = 使用 STD 命名空间
- 使用
LIBCPP_VERSION
检测libc++
现在,这是我在 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
我认为最后要检查的是 __APPLE__
定义,这里是:
$ 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
为什么我在使用 -std=c++11
时收到 error: no type named 'unique_ptr' in namespace 'std'
?
我认为这是四个测试用例。它尝试从以下项的叉积中练习四种配置:{C++03,C++11} x {libc++,libstdc++}。
- c++ -c 测试-clapple.cxx
- 好的
- c++ -stdlib=libc++ -c 测试-clapple.cxx
- 好的
- c++ -std=c++11 -c 测试-clapple.cxx
- 失败
- c++ -std=c++11 -stdlib=libc++ -c 测试-clapple.cxx
- 好的
这里是试车手。请务必在 OS X 上对其进行测试,以便在 2015 年获得 TR1 命名空间的全部效果。
$ 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;
}
And the CFE Devs specifically told me to use that code;
不,他们没有。如果你想使用 shared_ptr
,他们告诉你做类似的事情,因为对于 C++03 <tr1/memory>
定义 std::tr1::shared_ptr
而对于 C++11 <memory>
定义 std::shared_ptr
.
但是您没有使用 shared_ptr
。如果你想使用 auto_ptr
那么它只是 std::auto_ptr
,无处不在,它总是在 <memory>
.
中定义
我认为你误解了 Marshall 的评论,你把事情复杂化了。你引用的('In c++11, they are officially part of the standard, and live in the namespace std, just like vector and string. The include files no longer live in the "tr1" folder, either.')不是Apple-specific或Clang-specific,它适用于所有编译器。但是由于 auto_ptr
从来都不是 TR1 的一部分,也从来没有在 <tr1/memory>
中,因此 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
这对于现代编译器应该是正确的,但不适用于 XCode 附带的愚蠢配置,它是支持 C++11 和 GCC 4.2 的 libstdc++ 的现代版本的 Clang将近十年了,不支持 unique_ptr
.
为了处理默认的 OS X 工具链,这个有效:
#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
这通过使用 <forward_list>
的存在作为标准库 clang 正在使用的指标是否支持 std::unique_ptr
.
来工作
如果clang使用libc++作为标准库那么所有版本都支持unique_ptr
并且还提供<forward_list>
,所以测试通过
如果 clang 使用 libstdc++,那么是否支持 unique_ptr
取决于 libstdc++ 版本。 unique_ptr
已添加到 GCC 4.3 中的 libstdc++,这是添加 <forward_list>
的同一版本,因此如果 header 可用,那么 unique_ptr
也将可用。如果您将 clang 与 Apple 工具链(来自 GCC 4.2)附带的古老 libstdc++ 一起使用,则不支持 unique_ptr
,但也不支持 <forward_list>
,因此测试失败,您使用 auto_ptr
相反。
这应该适用于在野外发现的任何 GCC/libstdc++、Clang/libc++ 或 Clang/libstdc++ 组合。我不知道 VC++/Dinkumware 和 Clang/Dinkumware 需要什么,根据您的回答,您可能只需将第一个条件更改为:
#if __cplusplus >= 201103L || _MSC_VER >= 1600
我在 Apple 平台上尝试使用 unique_ptr
时遇到编译错误 -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>;
根据 Marshall Clow 的说法,我认为他是 C++ Standard Library with Clang and Apple 方面的专家:
Technical Report #1 (TR1) was a set of library additions to the C++03 standard. Representing the fact that they were not part of the "official" standard, they were placed in the namespace std::tr1.
In c++11, they are officially part of the standard, and live in the namespace std, just like vector and string. The include files no longer live in the "tr1" folder, either.
外卖:
- Apple 和 C++03 = 使用 TR1 命名空间
- Apple 和 C++11 = 使用 STD 命名空间
- 使用
LIBCPP_VERSION
检测libc++
现在,这是我在 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
我认为最后要检查的是 __APPLE__
定义,这里是:
$ 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
为什么我在使用 -std=c++11
时收到 error: no type named 'unique_ptr' in namespace 'std'
?
我认为这是四个测试用例。它尝试从以下项的叉积中练习四种配置:{C++03,C++11} x {libc++,libstdc++}。
- c++ -c 测试-clapple.cxx
- 好的
- c++ -stdlib=libc++ -c 测试-clapple.cxx
- 好的
- c++ -std=c++11 -c 测试-clapple.cxx
- 失败
- c++ -std=c++11 -stdlib=libc++ -c 测试-clapple.cxx
- 好的
这里是试车手。请务必在 OS X 上对其进行测试,以便在 2015 年获得 TR1 命名空间的全部效果。
$ 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;
}
And the CFE Devs specifically told me to use that code;
不,他们没有。如果你想使用 shared_ptr
,他们告诉你做类似的事情,因为对于 C++03 <tr1/memory>
定义 std::tr1::shared_ptr
而对于 C++11 <memory>
定义 std::shared_ptr
.
但是您没有使用 shared_ptr
。如果你想使用 auto_ptr
那么它只是 std::auto_ptr
,无处不在,它总是在 <memory>
.
我认为你误解了 Marshall 的评论,你把事情复杂化了。你引用的('In c++11, they are officially part of the standard, and live in the namespace std, just like vector and string. The include files no longer live in the "tr1" folder, either.')不是Apple-specific或Clang-specific,它适用于所有编译器。但是由于 auto_ptr
从来都不是 TR1 的一部分,也从来没有在 <tr1/memory>
中,因此 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
这对于现代编译器应该是正确的,但不适用于 XCode 附带的愚蠢配置,它是支持 C++11 和 GCC 4.2 的 libstdc++ 的现代版本的 Clang将近十年了,不支持 unique_ptr
.
为了处理默认的 OS X 工具链,这个有效:
#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
这通过使用 <forward_list>
的存在作为标准库 clang 正在使用的指标是否支持 std::unique_ptr
.
如果clang使用libc++作为标准库那么所有版本都支持unique_ptr
并且还提供<forward_list>
,所以测试通过
如果 clang 使用 libstdc++,那么是否支持 unique_ptr
取决于 libstdc++ 版本。 unique_ptr
已添加到 GCC 4.3 中的 libstdc++,这是添加 <forward_list>
的同一版本,因此如果 header 可用,那么 unique_ptr
也将可用。如果您将 clang 与 Apple 工具链(来自 GCC 4.2)附带的古老 libstdc++ 一起使用,则不支持 unique_ptr
,但也不支持 <forward_list>
,因此测试失败,您使用 auto_ptr
相反。
这应该适用于在野外发现的任何 GCC/libstdc++、Clang/libc++ 或 Clang/libstdc++ 组合。我不知道 VC++/Dinkumware 和 Clang/Dinkumware 需要什么,根据您的回答,您可能只需将第一个条件更改为:
#if __cplusplus >= 201103L || _MSC_VER >= 1600