我有一个类Filter,它process为各种输入重载了方法.
template< typename T >
class Filter
{
public:
void process(T arr[], size_t len);
T process(T one_value);
void process(std::array &arr);
void process(std::vector &v);
//... many other variants
using operator() = process; // How to write proper?
}
Run Code Online (Sandbox Code Playgroud)
我想简化用户代码省略process:filter.process(values)将成为filter(values).我不认为operator()为每个变体写一个重载是个好主意.必须存在更方便的解决方案吗?
因为你已经有混合模板; 为什么不尝试一个可变参数模板呢;
template <typename... Args>
auto operator()(Args&&... args)
// assuming non-reference returns
{
return process(std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)
另外; 如果从某些重载返回引用(未在OP中显示);
template <typename... Args>
decltype(auto) operator()(Args&&... args)
// caters for reference returns
{
return process(std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)
为了进一步完整和更广泛的用例; 如果需要,以下提供SFINAE友好的行为,并根据编译器,更短/更容易的错误消息;
template <typename... Args>
auto operator()(Args&&... args) -> decltype(process(std::forward<Args>(args)...))
// SFINAE support using a trailing decltype
{
return process(std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)
当然,只需模板化operator(),使用Universal Reference,然后完美地转发参数process.原因,您需要添加适当的标头.
template< typename T >
class Filter
{
public:
void process(T arr[], size_t len);
T process(T one_value);
void process(std::array &arr);
void process(std::vector &v);
//... many other variants
template<typename... Y>
auto operator () (Y&&... y)
-> decltype(process(std::declval<Y>()...))
{
return process(std::forward<Y>(y)...);
}
}
Run Code Online (Sandbox Code Playgroud)
但请注意,process必须在之前声明每个重载operator ()(...)- 谢谢TC
| 归档时间: |
|
| 查看次数: |
402 次 |
| 最近记录: |