std::auto_ptr 在我的模板类中编译,但不是 std::unique_ptr

Posted

技术标签:

【中文标题】std::auto_ptr 在我的模板类中编译,但不是 std::unique_ptr【英文标题】:std::auto_ptr compiles in my template class but not std::unique_ptr 【发布时间】:2013-10-07 22:27:59 【问题描述】:

我启动了一个模板类,它应该管理一个固定长度的双端队列。我正在寻找添加一个函数,该函数将返回转换为向量的数据。因为我不能确定这将使用良好的 NRVO(命名返回值优化)进行编译,并且理论上数据可能非常大,所以我决定将返回值包装在 unique_ptr 中(以避免在最后大量调用复制构造函数)。奇怪的是这没有编译:

 In file included from FixedDeque.cpp:8:
 FixedDeque.h:26: error: ISO C++ forbids declaration of 'unique_ptr' with no type
 FixedDeque.h:26: error: invalid use of '::'
 FixedDeque.h:26: error: expected ';' before '<' token
 FixedDeque.cpp:27: error: expected constructor, destructor, or type conversion before '<' token

我在 OS X 雪豹上使用 g++ 作为 NetBeans 中的编译器。

但是,当我更改完全相同的代码以使用 auto_ptr 时,整个事情都会编译。 unique_ptr 和 templates 有问题吗?仅供参考,我确实确保在这两种情况下连续的“”之间都有一个空格(以避免解释管道符号)。

这是我的代码,如果有人能阐明这个问题,我将不胜感激:

标题:

#include "deque"
#include "vector"
#include "memory"
template<typename T> class FixedDeque 
public:
  FixedDeque(int size);
  FixedDeque(const FixedDeque<T>& orig);
  virtual ~FixedDeque();
  // adding an auto_ptr/unique_ptr because not sure the C++ NRVO is applied in the compiler
  std::unique_ptr< std::vector<T> > getVectorCopy() const;
private:
  std::deque<T> _deq;
  int _maxSize;
;


#include "FixedDeque.h"
template<typename T> FixedDeque<T>::FixedDeque(int size)  : _deq(size), _maxSize(size)
 
template<typename T> FixedDeque<T>::FixedDeque(const FixedDeque<T>& orig) : _deq(orig._deq) 
template<typename T> FixedDeque<T>::~FixedDeque()   
template<typename T> std::unique_ptr< std::vector<T> > FixedDeque<T>::getVectorCopy() const

    std::vector<T>* apVector = new std::vector<T>();
    return( std::unique_ptr< std::vector<T> >(apVector) );
  

同样,只需将 unique_ptr 替换为 auto_ptr 就可以编译整个内容。我知道我的实现返回一个指向空向量的指针。我只是想专注于我在使用 unique_ptr 与 auto_ptr 时可能出现的问题。

谢谢!

【问题讨论】:

您的 C++ 版本是多少?你开启-std=c++11了吗? 应该是#include &lt;memory&gt;等。你用的是C++11编译器吗? 我使用的是 NetBeans 7.3.1,它应该有 C++11 作为标准。我在项目属性的“C++ 编译器”下将 C++ 标准设置为 C++11,它给了我:cc1plus:错误:无法识别的命令行选项“-std=c++11”。所以看起来我可能不得不升级我的 g++ 版本。我是从苹果的 XCode 3.x(最后一个兼容雪豹的版本)得到的——所以可能只需要升级 g++。 【参考方案1】:

您的代码大部分是正确的,只是您无法编译类模板。为了使它工作,你必须在头文件中声明和实现类模板,#include 头文件并在你的程序上实例化类模板。请看下面的例子:

// This is FixedDeque.hpp
#include <iostream>
#include <deque>
#include <vector>
#include <memory>

template<typename T> class FixedDeque 
public:
  FixedDeque(int size);
  FixedDeque(const FixedDeque<T>& orig);
  virtual ~FixedDeque();
  // adding an auto_ptr/unique_ptr because not sure the C++ NRVO is applied in the compiler
  std::unique_ptr< std::vector<T> > getVectorCopy() const;
private:
  std::deque<T> _deq;
  int _maxSize;
;

template<typename T> FixedDeque<T>::FixedDeque(int size)  : _deq(size), _maxSize(size)
 
template<typename T> FixedDeque<T>::FixedDeque(const FixedDeque<T>& orig) : _deq(orig._deq) 
template<typename T> FixedDeque<T>::~FixedDeque()   
template<typename T> std::unique_ptr< std::vector<T> > FixedDeque<T>::getVectorCopy() const

    std::vector<T>* apVector = new std::vector<T>();
    return( std::unique_ptr< std::vector<T> >(apVector) );
  

// This is FixedDeque_Test.cpp
int main() 
    FixedDeque<int> fdeque(10);
    std::unique_ptr<std::vector<int>> vec = fdeque.getVectorCopy();
    std::cout << vec->size() << std::endl;
    return 0;

【讨论】:

您好 Diego,非常感谢您的快速回复。它绝对看起来像一个编译器问题。如果您可以编译我的模板,那么您绝对可以使用它,我遇到的问题是它拒绝编译,除非我使用 auto_ptr 而不是 unique_ptr。我复制并粘贴了您的代码,但仍然遇到同样的问题(Snow Leopard 上的 g++)。如果您的意思是我可以将模板函数实现与声明放在同一个文件中,那么我也这样做了。感谢您的参与。 @user2835640 和其他人一样说您需要在编译器中启用 c++11 支持才能使用 std::unique_ptr。 @user2835640 好的,在 Snow Leopard 上,您可能没有 C++11 编译器。你可以试试 g++ -std=c++11 FixedDeque.cpp -o FixedDeque 吗?您也可以尝试使用 clang,如下所示:clang++ -std=c++11 -stdlib=libc++ FixedDeque.cpp -o FixedDeque。请在编译之前将我答案中的整个代码放在一个文件中。 迭戈,drescherjm,谢谢你的现场。正如我在上面的评论中提到的那样,我可能需要找到一种方法来升级我在雪豹上的 g++ 而不会破坏其他任何东西。我会辩论这个决定,但现在我会考虑解决这个问题。这是一个有趣的错误(在非 C++11 环境中使用 unique_ptr 模板)。谢谢大家 - 看起来是一个非常有用的帮助网站。我也会尝试安装 clang 编译器。 @user2835640 尝试将您的 XCode 更新到最新版本。它将带来一个支持 C++11 的更新的 clang,您将能够毫无问题地编译它。

以上是关于std::auto_ptr 在我的模板类中编译,但不是 std::unique_ptr的主要内容,如果未能解决你的问题,请参考以下文章

auto_ptr浅析

auto_ptr 的动态内存分配

为啥将 std::auto_ptr<> 与标准容器一起使用是错误的?

gcc 编译错误:模板类表中嵌套类 A ​​的成员在嵌套朋友类中不可见。为啥?

c++11 auto_ptr介绍

为啥我不能在我的类中内联函数? [复制]