c++ - 包装的 unique_ptr 的模板化 move 构造函数

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

我想要类似于 unique_ptr 的东西,但保证(在合理范围内)是非空的。我写了这个包含 unique_ptr 的类,我写了这个 move 构造函数,我希望它允许我从另一个指针 move 构造一个指针,只要底层的 unique_ptr 可以类似地 move 构造。所以,我首先尝试一些简单的东西;从指向整数的指针 move 构造指向整数的指针。

#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 在 move 构造变量 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

谢谢!

最佳答案

您正在尝试从另一个 Nonup 初始化 m_ptr,而不是它的 m_ptr。 move 构造函数的初始化程序应该是:

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

关于c++ - 包装的 unique_ptr 的模板化 move 构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13416458/

相关文章:

c++ - 如何通过不可变类型的 "pipeline"传递信息

C 指针数组随机改变地址

c++ - 为什么 move 指针变量不会将其设置为空?

C++:使用for循环允许用户将数字输入数组

javascript - 我可以在 iPhone 上运行 javascript 运行时(如 v8)吗?

c++ - 在初始化中使用新声明的变量 (int x = x+1)?

C++ 将换行从 CR+LF 更改为 LF

c - 使用条件语句从十六进制显示为字符

Java - 修改列表会修改包含列表的对象

C++11:延迟初始化的安全双重检查锁定。可能的?