所以,我有一个宏。
// swap_specialize.hpp
#include <algorithm>
#ifndef STD_SWAP_SPECIALIZE
#define STD_SWAP_SPECIALIZE( CLASSNAME ) \
namespace std { \
template<> inline \
void swap( CLASSNAME & lhs, CLASSNAME & rhs ) \
{ lhs.swap(rhs); } }
#endif
那么我有一个班级
// c.hpp
#include <vector>
#include "swap_specialize.hpp"
class C
{
public:
C();
void swap(C& rhs)
{
data_.swap(rhs.data_);
}
C& operator=(C rhs)
{
rhs.swap(*this);
return *this;
}
private:
std::vector<int> data_;
}
STD_SWAP_SPECIALIZE(C)
以这种方式使用宏来专门化std :: swap遵循编码约定吗?
答案 0 :(得分:6)
我会说如果提高可读性就没问题。判断自己。仅仅是我的两分钱:专业化std::swap
并不是真正做到这一点的正确方法。考虑一下这种情况:
my_stuff::C c, b;
// ...
swap(c, b);
// ...
如果您没有std::swap
或类似的内容,则无法找到using std::swap
。您应该在C
的命名空间中声明自己的交换:
void swap(C &a, C &b) {
a.swap(b);
}
现在,这也适用于上述情况,因为依赖于参数的查找在类的命名空间中搜索。代码交换类型未知的通用事物应该这样做:
using std::swap;
swap(a, b);
无论类型如何,如果在std::swap
的名称空间中没有更好的匹配交换,这将使用最佳匹配交换,并回退到a
。对std::swap
的调用进行硬编码会减少对不专门化std::swap
的类型的过短,而是决定在其名称空间中提供自己的交换。
这在另一方面是优越的:想象C
是一个模板。在这种情况下,您无法专门化std::swap
。但只是定义自己的交换,这非常好。
template<typename T>
void swap(C<T> &a, C<T> &b) {
a.swap(b);
}
这也是实现std::string
和其他类的交换的方式。
答案 1 :(得分:0)
我认为它不会给你带来太大的影响。对于非模板类,它可以为您节省很少的行。对于模板类,当你想要专门化(即所有T
)时,它就行不通。
答案 2 :(得分:0)
假设您正在使用STD_SWAP_SPECIALIZE()
用于其他许多类,我认为这是完全合理的。毕竟,拥有一系列
STD_SWAP_SPECIALIZE(Foo)
STD_SWAP_SPECIALIZE(Bar)
STD_SWAP_SPECIALIZE(Baz)
比无限扩展代码。此外,如果STD_SWAP_SPECIALIZE
的扩展稍微大一点,那么宏定义会在需要更改时在单个位置为您提供代码。 (因为模板定义在你的例子中非常小,所以它可能是一个没有实际意义的点。)