简体   繁体   English

如何为我的类型正确专门化 std::swap?

[英]How to properly specialize std::swap for my types?

After I've managed to overload std::swap for my class type now I want to specialize it rather than overload it since the standard allows adding template specializations to namespace std .在我设法为我的 class 类型重载std::swap之后,现在我想专门化它而不是重载它,因为标准允许将模板专门化添加到命名空间std Here is my example:这是我的例子:

class Foo{
public:
    Foo(){
        std::cout << "Foo()\n";
    }
    Foo(Foo const&){
        std::cout << "Foo(Foo const&)\n";
    }
    Foo(Foo&&){
        std::cout << "Foo(Foo&&)\n";
    }
    Foo& operator=(Foo const&){
        std::cout << "operator=(Foo const&)\n";
        return *this;
    }
    Foo& operator=(Foo&&){
        std::cout << "operator=(Foo&&)\n";
        return *this;
    }
    ~Foo(){
        std::cout << "~Foo()\n";
    }
};

class VecFoo;
namespace std{
    template <>
    void swap<VecFoo>(VecFoo&, VecFoo&);
}

class VecFoo{
    Foo* pFoo_ = new Foo[10];
    template<>
    friend void std::swap<VecFoo>(VecFoo&, VecFoo&);
};

template <>
void std::swap<VecFo>(VecFoo& lhs, VecFoo& rhs){
    std::cout << "template <> void std::swap(VecFoo&, VecFoo&)\n";
    std::swap(lhs.pFoo_, rhs.pFoo_);
}


int main(){

    VecFoo vf1, vf2;
    using std::swap;
    swap(vf1, vf2);

}
  • I don't know why it doesn't compile and I get an error: /usr/include/c++/10/type_traits|2195| required by substitution of 'template<class... _Cond> using _Require = std::__enable_if_t<std::__and_< <template-parameter-1-1> >::value> [with _Cond = {std::__not_<std::__is_tuple_like<VecFoo> >, std::is_move_constructible<VecFoo>, std::is_move_assignable<VecFoo>}]'|我不知道为什么它不能编译并且我得到一个错误: /usr/include/c++/10/type_traits|2195| required by substitution of 'template<class... _Cond> using _Require = std::__enable_if_t<std::__and_< <template-parameter-1-1> >::value> [with _Cond = {std::__not_<std::__is_tuple_like<VecFoo> >, std::is_move_constructible<VecFoo>, std::is_move_assignable<VecFoo>}]'| /usr/include/c++/10/type_traits|2195| required by substitution of 'template<class... _Cond> using _Require = std::__enable_if_t<std::__and_< <template-parameter-1-1> >::value> [with _Cond = {std::__not_<std::__is_tuple_like<VecFoo> >, std::is_move_constructible<VecFoo>, std::is_move_assignable<VecFoo>}]'|

So what is the problem here and how could I correctly specialize it?那么这里的问题是什么,我怎样才能正确地专门化它呢?

  • PS: please don't argue about RAII that I am not achieving in my class VecFoo and the memory leak there because it is not that my problem here. PS:请不要争论我在 class VecFoo和 memory 中没有实现的 RAII,因为这不是我的问题。

This is pretty simple really.这真的很简单。 You don't need the template but you do need to be in the correct namespace.您不需要模板,但您确实需要位于正确的命名空间中。

namespace std {
void swap(VecFoo& lhs, VecFoo& rhs) {
    std::cout << "void swap(VecFoo&, VecFoo&)\n";
    //do your custom swap here!!!
}
}

std::move requires the class to be move-assignable and move-constructible, but the class VecFoo is not any of them. std::move要求 class 可以移动分配和移动构造,但 class VecFoo不是其中的任何一个。

You added a bunch of method to support these constraints in the class Foo , which didn't requires any (you are swapping pointers).您在 class Foo添加了一堆方法来支持这些约束,这不需要任何(您正在交换指针)。

Also, there is a typo in the swap declaration: it says std::swap<VecFo> instead of std::swap<VecFoo> .此外,交换声明中有一个错字:它说std::swap<VecFo>而不是std::swap<VecFoo>

Finally, I would recommend NOT using friend .最后,我建议不要使用friend Just add a method swap to the class and put the logic there.只需将方法swap添加到 class 并将逻辑放在那里。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM