为C ++模板类提供swap()会打破std :: swap()?

我试图在自定义Matrix类中实现copy-and-swap成语,并且按照链接问题中建议的方式执行swap()时遇到了一些问题:

(我使用的编译器是MS VS2010 IDE的编译器,方言是老式的C ++ 03。)

// matrix.h

namespace my_space 
{

template<typename T> class Matrix
{
public:
    /* ... */

    friend void swap(Matrix<T> &first, Matrix<T> &second)
    {
        using std::swap;
        swap(first.width_, second.width_);
        swap(first.height_, second.height_);
        swap(first.data_, second.data_);
    }
};

} // namespace

现在我无法在驻留在此命名空间中的函数的代码中使用常规std :: swap():

// some_code.cpp:
#include "matrix.h"
#include <algorithm>

using namespace my_space;
using namespace std;

// SomeClass is part of my_space!
void SomeClass::some_function()
{
    int a = 3, b = 7;
    swap(a,b);  // I wan't std::swap!
}

不幸的是,出于某种原因, my_space::swap()似乎别名了所有其他调用std::swap() ,我不知道为什么因为参数不适合,ADL应该赞成std::swap

1>f:srcsome_code.cpp(653): error C3767: 'swap': candidate function(s) not accessible
1>          could be the friend function at 'f:srcmatrix.h(63)' : 'swap'  [may be found via argument-dependent lookup]

(错误重复10次,我试图使用std::swap每一行)

my_spacemy_space::swap()总是会否决std::swap() ,即使参数不适合? 它不像std::swap()不可见,并且在创建my_space::swap()之前它工作正常。


STL容器采用的方法使用成员函数,然后重载静态函数。 例如:

template<class T, class Alloc=std::allocator<T> >
class vector
{
   T *data;
   size_t n;
   size_t max_n;
public:
   void swap(vector<T, Alloc> &other)
   {
      swap(this->data, other.data);
      swap(this->n, other.n);
      swap(this->max_n, other.max_n);
   }
};

template<class T, class A>
void swap(vector<T, A> &lhs, vector<T, A> &rhs)
{
   lhs.swap(rhs);
}

在建议的Matrix类中,只需采用相同的方法即可...

namespace my_space
{
template<typename T>
class Matrix
{
   unsigned width_;
   unsigned height_;
   std::vector<T> data_;
public:
   void swap(Matrix<T> &other)
   {
      std::swap(this->width_, other.width_);
      std::swap(this->height_, other.height_);
      std::swap(this->data_, other.data_);  // calls this->data_.swap(other.data_);
   }
};
}

namespace std
{
   template<typename T>
   void swap(my_space::Matrix<T> &lhs, my_space::Matrix<T> &rhs)
   {
      lhs.swap(rhs);
   }
}

Matrix包含以下行:

template<typename U> friend void swap(Matrix<U> &first, Matrix<U> &second);

并在类之外定义swap 。 您function template has already been defined获取错误function template has already been defined的原因,因为您定义了Matrix模板中的friend函数,因此Matrix<unsigned short>Matrix<char>每个实例都将包含与交换函数相同的定义。


以下内容适合VC ++ 2010 SP1:

Matrix.h:

#pragma once

#include <algorithm>
#include <vector>

namespace my_space
{
    template<typename T>
    class Matrix
    {
    public:
        Matrix(unsigned const w, unsigned const h)
          : width_(w), height_(h), data_(w * h)
        { }

    private:
        unsigned width_;
        unsigned height_;
        std::vector<T> data_;

        friend void swap(Matrix& lhs, Matrix& rhs)
        {
            using std::swap;
            swap(lhs.width_,  rhs.width_);
            swap(lhs.height_, rhs.height_);
            swap(lhs.data_,   rhs.data_);
        }
    };
}

的.cpp:

#include "Matrix.h"

int main()
{
    using namespace my_space;
    using std::swap;

    int a(0), b(1);
    swap(a, b);

    Matrix<int> c(2, 3), d(4, 5);
    swap(c, d);

    Matrix<short> e(6, 7), f(8, 9);
    swap(e, f);
}

由于您没有发布SSCCE(提示,提示),因此很难确切地知道您的问题出在哪里,但您可以以此为起点来缩小问题范围。

链接地址: http://www.djcxy.com/p/72933.html

上一篇: Providing swap() for a C++ template class breaks std::swap()?

下一篇: how to provide a swap function for my class?