为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_space
, my_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()?