is_assignable和std :: unique_ptr

时间:2018-12-21 09:48:00

标签: c++ move assignment-operator

Here是来自gcc live demo

的测试文件
struct do_nothing
{
    template <class T>
    void operator()(T*) {}
};

int
main()
{
    int i = 0;
    std::unique_ptr<int, do_nothing> p1(&i);
    std::unique_ptr<int> p2;
    static_assert(!std::is_assignable<decltype(p2), decltype(p1)>::value, ""); // note ! here.    
}

std::is_assignable

  

如果表达式std::declval<T>() = std::declval<U>()在未求值的上下文中格式正确,请提供等于true的成员常量值。否则,值为false。就像从与这两种类型都不相关的上下文中一样执行访问检查。

std::declval

template<class T>
typename std::add_rvalue_reference<T>::type declval() noexcept;
  

返回类型为T&&,除非T无效(可能是cv限定),在这种情况下返回类型为T。

让我们看看MoveAssignOnly

struct MoveAssignOnly {
  MoveAssignOnly &operator=(MoveAssignOnly &) = delete;
  MoveAssignOnly &operator=(MoveAssignOnly &&) = default;
};

int main()
{
    static_assert(
    not std::is_assignable<MoveAssignOnly, MoveAssignOnly>::value, "");
}

live demo

error: static_assert failed due to requirement '!std::is_assignable<MoveAssignOnly, MoveAssignOnly>::value'

是的,由于提供了移动分配而无法编译

让我们回到gcc's test filestd::unique_ptr。我们知道,std::unique_ptr also has move assignments

但是,与struct MoveAssignOnly不同,static_assert(!std::is_assignable<decltype(p2), decltype(p1)>::value, "");(更清楚地说,static_assert(!std::is_assignable<std::unique_ptr<int>, std::unique_ptr<int, do_nothing>>::value, "");编译很愉快。

我一直在努力解决libcxx的unique_ptr的实现问题,但是仍然无法弄清楚:std::unique_ptr如何不可分配! is_assignablestd::unique_ptr提供了移动分配吗?

1 个答案:

答案 0 :(得分:4)

p1p2是不同的类型。与shared_ptr不同,unique_ptr的删除器是指针类型的一部分。这意味着如果两个unique_ptr的删除器类型不同,则移动分配运算符不允许您在两个unique_ptr之间分配(甚至移动分配)。

unique_ptr还提供了一个赋值运算符模板,该模板允许从struct do_nothing { template <class T> void operator()(T*) {} template <class T> operator std::default_delete<T>() { return {}; } }; int main() { int i = 0; std::unique_ptr<int, do_nothing> p1(&i); std::unique_ptr<int> p2; static_assert(!std::is_assignable<decltype(p2), decltype(p1)>::value, ""); // note ! here. } 的右值进行赋值,以使用其他删除器进行赋值,但这些删除器必须是可分配的(请参见reference)。因此,您可以通过使删除器可分配来使静态断言触发:

1. Read the video frames using opencv [You can use moviepy as well]
2. For each  frame : a) Preprocess the frame before sending to the network
                b) Get the output as coordinates
                c) Use opencv to draw the predicted bounding box along with the classified label in the frame
                d) Add the current frame to the new video_writer object of opencv
                e) Finally save it as a video

3. Display the video

[Live example]