如何删除相似的引用限定成员函数之间的代码重复?
How do I remove code duplication between similar ref-qualified member functions?
与 How do I remove code duplication between similar const and non-const member functions? 类似,我想删除几乎相同的成员函数之间的代码重复,ref 限定符除外。
假设我有一个 class 是这样的:
class MyStringBuilder
{
std::string member;
public:
// Other functions
std::string create() const& {
// Some work
std::string result = member;
// More work
return result;
}
std::string create() && {
// Some work
std::string result = std::move(member);
// More work
return result;
}
};
我们想要为构建器对象执行此操作并不是不可想象的,因为如果我们完成 MyStringBuilder
.
它会保存一个副本
const&
版本和&&
版本的代码除了使用成员的地方是一样的。这两个函数之间的唯一区别是 &&
版本 std::move
引用任何成员。
如何避免代码重复?
你可以做的一件事是你可以在非成员函数中实现逻辑,并将 *this
的类型作为模板参数:
class MyStringBuilder
{
std::string member;
template<typename Self>
static std::string create_impl(Self&& self) {
// Some work
std::string result = std::forward<Self>(self).member;
// More work
return result;
}
public:
// Other functions
std::string create() const& {
return create_impl(*this);
}
std::string create() && {
return create_impl(std::move(*this));
}
};
与 How do I remove code duplication between similar const and non-const member functions? 类似,我想删除几乎相同的成员函数之间的代码重复,ref 限定符除外。
假设我有一个 class 是这样的:
class MyStringBuilder
{
std::string member;
public:
// Other functions
std::string create() const& {
// Some work
std::string result = member;
// More work
return result;
}
std::string create() && {
// Some work
std::string result = std::move(member);
// More work
return result;
}
};
我们想要为构建器对象执行此操作并不是不可想象的,因为如果我们完成 MyStringBuilder
.
const&
版本和&&
版本的代码除了使用成员的地方是一样的。这两个函数之间的唯一区别是 &&
版本 std::move
引用任何成员。
如何避免代码重复?
你可以做的一件事是你可以在非成员函数中实现逻辑,并将 *this
的类型作为模板参数:
class MyStringBuilder
{
std::string member;
template<typename Self>
static std::string create_impl(Self&& self) {
// Some work
std::string result = std::forward<Self>(self).member;
// More work
return result;
}
public:
// Other functions
std::string create() const& {
return create_impl(*this);
}
std::string create() && {
return create_impl(std::move(*this));
}
};