c++ - 如何在专门化交换功能时使用 gcc8 修复编译错误/

标签 c++ compiler-errors template-specialization rvalue gcc8

我正在尝试为我的类编译专门化函数 std::swap 的代码。 但是我遇到了由于右值构造函数而发生的问题(当我评论该行时它有效)

我正在使用 g++ (GCC) 8.2.1 20180905 (Red Hat 8.2.1-3) 进行编译 和 g++ -std=c++14 -Wall 那些选项

#include <iostream>
#include <utility>

namespace ns1
{
class Foo 
{
public:
    Foo();
    Foo(const Foo& that) {};
    Foo(Foo&& that) {};  // <--- work when commented
    ~Foo();  
    void swap(Foo &that) {};
};

inline void swap(Foo &lhs, Foo &rhs)
{
   lhs.swap(rhs);
}
}  // namespace ns1

namespace std {

template <>
inline void swap(ns1::Foo &lhs, ns1::Foo &rhs)
{
   lhs.swap(rhs);
}

} // namespace std

我有以下错误信息:

 error: template-id 'swap<>' for 'void std::swap(ns1::Foo&, ns1::Foo&)' does not match any template declaration
 inline void swap(ns1::Foo &lhs, ns1::Foo &rhs)
             ^~~~
In file included from /opt/rh/devtoolset-8/root/usr/include/c++/8/string:52,
                 from /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/locale_classes.h:40,
                 from /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/ios_base.h:41,
                 from /opt/rh/devtoolset-8/root/usr/include/c++/8/ios:42,
                 from /opt/rh/devtoolset-8/root/usr/include/c++/8/ostream:38,
                 from /opt/rh/devtoolset-8/root/usr/include/c++/8/iostream:39,
                 from toto.cpp:1:
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/basic_string.h:6276:5: note: candidates are: 'template<class _CharT, class _Traits, class _Alloc> void std::swap(std::basic_string<_CharT, _Traits, _Alloc>&, std::basic_string<_CharT, _Traits, _Alloc>&)'
     swap(basic_string<_CharT, _Traits, _Alloc>& __lhs,
     ^~~~
In file included from /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/stl_algobase.h:64,
                 from /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/char_traits.h:39,
                 from /opt/rh/devtoolset-8/root/usr/include/c++/8/ios:40,
                 from /opt/rh/devtoolset-8/root/usr/include/c++/8/ostream:38,
                 from /opt/rh/devtoolset-8/root/usr/include/c++/8/iostream:39,
                 from toto.cpp:1:

最佳答案

您看到的错误是因为提供用户定义的移动构造函数会阻止编译器合成移动赋值运算符,从而使您的类不可移动赋值。 根据 cppreferece , swap 中的 T 必须是可移动赋值的。

要修复它,请同时提供移动赋值运算符,demo

Foo& operator=(Foo&& other) {return *this;}
Foo& operator= (const Foo& other) { return *this; }

另请查看 rule of five

关于c++ - 如何在专门化交换功能时使用 gcc8 修复编译错误/,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58120029/

相关文章:

javascript - Google 闭包编译器,JSC_INEXISTENT_PROPERTY 问题与 mixin/extend

c++ - 避免使用模板函数的 if-else 语句

c++ - 成员模板实例化

python - 如何在 Windows GUI 应用程序中将嵌入式 Python 连接到控制台的 I/O?

c++ - 如何修复 “error: invalid use of non-static data member '树::root'” error in c++?

c# - 如何解决错误CS1525无效表达词 '='?

模板 <char*, char*> 对象的 c++ 排序 vector

c++ - 如何选择部分模板特化?

c++ - 为 const global 跳过 extern 仍然可以正常工作

c++ - 嵌套命名空间,纠正静态库设计问题