所有重载方法的别名?

kyb*_*kyb 7 c++ overloading

我有一个类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()为每个变体写一个重载是个好主意.必须存在更方便的解决方案吗?

Nia*_*all 8

因为你已经有混合模板; 为什么不尝试一个可变参数模板呢;

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)

  • @DanKorn我认为用符合当前标准的C++代码回答`c ++`标签是很常见的.也就是说,我不认为`c ++`标签意味着C++ 03或任何其他特定标准. (4认同)
  • 没有绕过任何类型检查,也没有转换.`process`将接收提供给`operator()`的参数. (2认同)
  • @DanKorn现在当前是C++ 14.至于传递参数的类型安全性无法通过重载解析来解析,那么在对`operator()`的进程调用中将生成编译器错误.只要OP具有他们想要定义的所有进程,调用带有错误参数的`()`就像调用带有错误参数的`process`一样. (2认同)

Whi*_*TiM 8

当然,只需模板化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