我有一个类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?
}
我想简化省略process
的用户代码:filter.process(values)
将成为filter(values)
。我不认为为每个变体编写一个重载的operator()
是个好主意。必须存在更方便的解决方案吗?
答案 0 :(得分:8)
当然,只需模板operator()
,使用通用参考,并将参数完美转发到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)...);
}
}
但请注意,必须在process
之前声明operator ()(...)
的每次重载 - 谢谢T.C
答案 1 :(得分:7)
由于你已经有混合模板;为什么不尝试一个可变参数模板;
template <typename... Args>
auto operator()(Args&&... args)
// assuming non-reference returns
{
return process(std::forward<Args>(args)...);
}
可替换地;如果从某些重载返回引用(未在OP中显示);
template <typename... Args>
decltype(auto) operator()(Args&&... args)
// caters for reference returns
{
return process(std::forward<Args>(args)...);
}
进一步完整和更广泛的用例;如果需要,以下提供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)...);
}
答案 2 :(得分:-4)
好的,你编辑了这个问题,所以这就回答你现在要问的问题,具体来说,“我想简化用户代码省略过程:filter.process(values)将成为过滤器(值)。”
只需将所有这些重载转换为构造函数,如下所示:
template< typename T >
class Filter
{
public:
void Filter(T arr[], size_t len);
T Filter(T one_value);
void Filter(std::array &arr);
void Filter(std::vector &v);
//... many other variants
};