在LLVM/Clang下编译时,名称空间"std"中没有名为"unique_ptr"的类型 [英] No type named 'unique_ptr' in namespace 'std' when compiling under LLVM/Clang

查看:116
本文介绍了在LLVM/Clang下编译时,名称空间"std"中没有名为"unique_ptr"的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试在-std=c++11的Apple平台上使用unique_ptr时,捕获了编译错误:

I'm catching a compile error when attempting to use unique_ptr on Apple platforms with -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 ++标准库的专家,叮当声和苹果:

According to Marshall Clow, who I consider an expert on the C++ Standard Library with Clang and Apple:

技术报告1(TR1)是C ++ 03的一组库添加项 标准.表示它们不属于 正式"标准,它们被放置在命名空间std :: tr1中.

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.

在c ++ 11中,它们正式成为标准的一部分,并存在于 命名空间std,就像vector和string.包含文件否 也可以将其保存在"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++
  • Apple and C++03 = use TR1 namespace
  • Apple and C++11 = use STD namespace
  • Use LIBCPP_VERSION to detect libc++

现在,这是我在smartptr.h中拥有的东西:

Now, here's what I have in 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__定义,这里是:

I think the last thing to check is the __APPLE__ define, and here it is:

$ 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' ?

Why am I receiving a error: no type named 'unique_ptr' in namespace 'std' when using -std=c++11?

我认为这是四个测试用例.它尝试从{C ++ 03,C ++ 11} x {libc ++,libstdc ++}的叉积中执行四种配置.

I think these are the four test cases. It attempts to exercise the four configurations from the cross product of: {C++03,C++11} x {libc++,libstdc++}.

  • c ++ -c test-clapple.cxx
    • 确定
    • c++ -c test-clapple.cxx
      • OK
      • 确定
      • 失败
      • 确定

      这里是测试驱动程序.请确保在OS X上对其进行测试,以便在2015年获得TR1名称空间的完整效果.

      Here is the test driver. Be sure to test it on OS X so you get the full effects of the TR1 namespace in 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;
      }
      

      推荐答案

      CFE开发人员专门告诉我使用该代码;

      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.

      No they didn't. They told you to do something similar if you want to use shared_ptr, because for C++03 <tr1/memory> defines std::tr1::shared_ptr and for C++11 <memory> defines std::shared_ptr.

      但是您没有使用shared_ptr.如果要使用auto_ptr,则它随处都是std::auto_ptr,始终在<memory>中定义.

      But you're not using shared_ptr. If you want to use auto_ptr then it's just std::auto_ptr, everywhere, which is always defined in <memory>.

      我认为您误解了马歇尔的评论,并且使事情变得过于复杂.您所引用的内容('在c ++ 11中,它们正式成为标准的一部分,并且像vector和string一样位于std命名空间中.include文件也不再位于"tr1"文件夹中. ')不是特定于Apple或Clang的,它适用于所有编译器.但是,由于auto_ptr从来都不是TR1的一部分,也从来不在<tr1/memory>中,因此TR1的内容现在位于命名空间std中是无关紧要的,因为您要使用的内容从未包含在TR1中.

      I think you've misunderstood Marshall's comment and you're overcomplicating things. What you quoted ('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.') is not Apple-specific or Clang-specific, it applies to all compilers. But since auto_ptr was never part of TR1 and never in <tr1/memory> it's irrelevant that the contents of TR1 are now in namespace std, because what you're trying to use was never included in TR1.

      您不应该在这里完全使用TR1 .

      You should not be using TR1 at all here.

      # 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附带的愚蠢配置,XCode是Clang的现代版本,支持C ++ 11和GCC 4.2中的libstdc ++,已有近十年的历史了并且不支持unique_ptr.

      This should be correct for modern compilers, but won't work on the stupid configuration that comes with XCode, which is a modern version of Clang that supports C++11 and the libstdc++ from GCC 4.2 which is nearly ten years old and doesn't support unique_ptr.

      要处理默认的OS X工具链,请执行以下操作:

      To cope with the default OS X toolchain this works:

      #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的指示器来起作用.

      This works by using the presence of <forward_list> as an indicator of whether the standard library clang is using supports std::unique_ptr.

      如果clang使用libc ++作为其标准库,则所有版本均支持unique_ptr并提供<forward_list>,因此测试通过.

      If clang is using libc++ as its standard library then all versions support unique_ptr and also provide <forward_list>, so the test passes.

      如果clang使用libstdc ++,则是否支持unique_ptr取决于libstdc ++版本. unique_ptr在GCC 4.3中添加到libstdc ++,与添加<forward_list>的版本相同,因此,如果该标头可用,那么unique_ptr也将可用.如果使用clang和Apple工具链附带的古老libstdc ++(来自GCC 4.2),则不支持unique_ptr,但不支持<forward_list>,因此测试失败,请改用auto_ptr.

      If clang is using libstdc++ then whether unique_ptr is supported depends on the libstdc++ version. unique_ptr was added to libstdc++ in GCC 4.3, which is the same version that added <forward_list>, so if that header is available then unique_ptr will be too. If you are using clang with the ancient libstdc++ that ships with the Apple toolchains (from GCC 4.2) then unique_ptr is not supported, but neither is <forward_list>, so the test fails and you use auto_ptr instead.

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

      That should work for any GCC/libstdc++, Clang/libc++ or Clang/libstdc++ combination found in the wild. I don't know what is needed for VC++/Dinkumware and Clang/Dinkumware, from your answer it looks like maybe you would just change the first condition to:

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

      这篇关于在LLVM/Clang下编译时,名称空间"std"中没有名为"unique_ptr"的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆