问题描述
假设我正在编写一个库,并且在某个时候,有一些代码想要对用户提供的类型的对象做一些特定的事情。以 swap
为例,虽然函数可以是任意的。什么是重要的:
在编译时在 C++ 中有两种主要的方法来做这样的事情:
- 函数重载
- 类模板特化
这些都不是理想的:
因此,我的想法是 - 为什么不能两者兼而有之?事实上,一些 STL 功能提供了 2 种甚至更多的自定义行为方式。典型的STL算法提供3:
- 提供将用作函子实现的额外函数参数(通常为 lambda)
- 重载特定类型的特定运算符
- 专门化属于标准库的特定类模板
在我的情况下,第一个选项(额外参数)是不可能的,因为假定的库不会立即使用该函子。
// A
namespace lib {
template <typename T>
struct swapper // can be specialized
{
void operator()(T& lhs,T& rhs) const noexcept
{
// default impl
}
};
template <typename T>
void swap(T& lhs,T& rhs) noexcept // can be overloaded
{
swapper<T>()(lhs,rhs);
}
template <typename T>
void core_function(/* ... */)
{
T t1 = /* ... */;
T t2 = /* ... */;
/* ... */
swap(t1,t2);
/* ... */
}
}
// B
namespace lib {
template <typename T>
void swap(T& lhs,T& rhs) noexcept // can be overloaded
{
// default impl
}
template <typename T>
struct swapper // can be specialized
{
void operator()(T& lhs,T& rhs) const noexcept
{
swap(lhs,rhs);
}
};
template <typename T>
void core_function(/* ... */)
{
T t1 = /* ... */;
T t2 = /* ... */;
/* ... */
swapper<T>()(t1,t2);
/* ... */
}
}
// user code (the same for both)
namespace user {
struct user_type { /* ... */ };
// customization through overloading
void swap(user_type& lhs,user_type& rhs) noexcept
{
// ...
}
// customization through class template specialization
template <>
struct swapper<user_type>
{
void swap(user_type& lhs,user_type& rhs) const noexcept
{
// ...
}
};
}
问题是 - 哪个实现更好 - A 还是 B? (函数,主类模板)调用哪个的顺序有什么区别吗?这两种实现方式各有优缺点吗?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)