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 <memory>
等。你用的是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的主要内容,如果未能解决你的问题,请参考以下文章
为啥将 std::auto_ptr<> 与标准容器一起使用是错误的?