包装的unique_ptr的模板化移动ctor

时间:2012-11-16 12:18:53

标签: c++ pointers c++11 move-semantics unique-ptr

我想要的东西就像unique_ptr,但保证(在合理范围内)是非null的。我写了这个包含unique_ptr的类,我编写了这个移动构造函数,我希望它能让我移动 - 构造我的一个指针,只要底层的unique_ptr可以类似地移动构造。所以,我首先尝试一些简单的东西;从指向int的指针移动构造指向int的指针。

#include <memory>
#include <utility>
#include <cassert>


template<
    typename T
    > 
class Nonup
{
    private:

        std::unique_ptr<T> m_ptr;

    public:

        explicit Nonup( T* p )
        : m_ptr( p )
        { assert( p ); }

        Nonup( const Nonup& ) = delete;
        Nonup& operator=( const Nonup& ) = delete;

        template<typename U>
        Nonup( Nonup<U>&& old )
        :
            m_ptr( std::move( old ) )
        {}

        Nonup& operator=( Nonup&& rhs ) = default;

        decltype( *m_ptr ) operator*() const { return *m_ptr; }
};


int main()
{
    Nonup<int> first( new int( 42 ) );

    Nonup<int> second( std::move( first ) );

    return 0;
}

为什么g ++ 4.7.0会在变量second的移动构造中出错? “g ++ -std = c ++ 11 main.cpp”的输出如下。

main.cpp: In instantiation of ‘Nonup<T>::Nonup(Nonup<U>&&) [with U = int; T = int]’:
main.cpp:40:43:   required from here
main.cpp:27:37: error: no matching function for call to ‘std::unique_ptr<int, std::default_delete<int> >::unique_ptr(std::remove_reference<Nonup<int>&>::type)’
main.cpp:27:37: note: candidates are:
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/memory:86:0,
                 from main.cpp:1:
/usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:164:2: note: template<class _Up, class> std::unique_ptr::unique_ptr(std::auto_ptr<_Up>&&)
/usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:164:2: note:   template argument deduction/substitution failed:
main.cpp:27:37: note:   ‘std::remove_reference<Nonup<int>&>::type {aka Nonup<int>}’ is not derived from ‘std::auto_ptr<_Up>’
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/memory:86:0,
                 from main.cpp:1:
/usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:155:2: note: template<class _Up, class _Ep, class> std::unique_ptr::unique_ptr(std::unique_ptr<_Up, _Ep>&&)
/usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:155:2: note:   template argument deduction/substitution failed:
main.cpp:27:37: note:   ‘std::remove_reference<Nonup<int>&>::type {aka Nonup<int>}’ is not derived from ‘std::unique_ptr<_Up, _Ep>’
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/memory:86:0,
                 from main.cpp:1:
/usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:142:7: note: std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp, _Dp>&&) [with _Tp = int; _Dp = std::default_delete<int>]
/usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:142:7: note:   no known conversion for argument 1 from ‘std::remove_reference<Nonup<int>&>::type {aka Nonup<int>}’ to ‘std::unique_ptr<int, std::default_delete<int> >&&’
/usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:136:17: note: constexpr std::unique_ptr<_Tp, _Dp>::unique_ptr(std::nullptr_t) [with _Tp = int; _Dp = std::default_delete<int>; std::nullptr_t = std::nullptr_t]
/usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:136:17: note:   no known conversion for argument 1 from ‘std::remove_reference<Nonup<int>&>::type {aka Nonup<int>}’ to ‘std::nullptr_t’
/usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:130:7: note: std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp, _Dp>::pointer, typename std::remove_reference<_To>::type&&) [with _Tp = int; _Dp = std::default_delete<int>; std::unique_ptr<_Tp, _Dp>::pointer = int*; typename std::remove_reference<_To>::type = std::default_delete<int>]
/usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:130:7: note:   candidate expects 2 arguments, 1 provided
/usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:125:7: note: std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp, _Dp>::pointer, typename std::conditional<std::is_reference<_Dp>::value, _Dp, const _Dp&>::type) [with _Tp = int; _Dp = std::default_delete<int>; std::unique_ptr<_Tp, _Dp>::pointer = int*; typename std::conditional<std::is_reference<_Dp>::value, _Dp, const _Dp&>::type = const std::default_delete<int>&]
/usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:125:7: note:   candidate expects 2 arguments, 1 provided
/usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:120:7: note: std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp, _Dp>::pointer) [with _Tp = int; _Dp = std::default_delete<int>; std::unique_ptr<_Tp, _Dp>::pointer = int*]
/usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:120:7: note:   no known conversion for argument 1 from ‘std::remove_reference<Nonup<int>&>::type {aka Nonup<int>}’ to ‘std::unique_ptr<int, std::default_delete<int> >::pointer {aka int*}’
/usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:114:17: note: constexpr std::unique_ptr<_Tp, _Dp>::unique_ptr() [with _Tp = int; _Dp = std::default_delete<int>]
/usr/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/bits/unique_ptr.h:114:17: note:   candidate expects 0 arguments, 1 provided

谢谢!

1 个答案:

答案 0 :(得分:1)

您尝试从其他m_ptr初始化Nonup,而不是m_ptr。移动构造函数的初始化应该是:

m_ptr( std::move( old.m_ptr ) )
                     ^^^^^^