【问题标题】:Member function traits成员函数特征
【发布时间】:2014-07-30 19:02:59
【问题描述】:

我正在编写一个包含成员函数的模板类,以减少一些调用 - 如果某些条件为真,则不需要调用成员函数。签名看起来像这样

template <typename MemFuncType, MemFuncType> class MemberWrapper;

我可以这样专门化它:

template <typename R, typename T, R T::* MemFunc> class MemberWrapper<R T::*, MemFunc>{};

我还想限制R T::* 的参数数量。我该怎么做?

我能想到的唯一解决方案是通过提供基于返回类型、函数类型、参数列表和 cv 限定符的部分特化来实现成员函数特征类。这将导致像当前的std::mem_fnoverloads 这样的繁琐实现。有没有更好的方法?

编辑:将Ret 更改为R。正如 cmets 中所指出的,它并不是真正的返回类型,并且特化无效。

【问题讨论】:

  • 用例是什么?展示你打算如何使用它。为什么std::function&lt;&gt; 不适合?
  • Ret T::* 不是成员函数指针类型。
  • @0x499602D2 其实是这样。但是Ret 将——尽管它的名字——不是返回的类型,而是一个函数类型。类似void(int,int).

标签: c++ templates c++11 variadic-templates


【解决方案1】:

不要试图把所有东西都放在一个类中。成员函数是作为类成员的函数。因此,首先创建一些功能特征类,例如

template< typename T >
class function_traits
{
  static_assert( sizeof( T ) == 0,
                 "function_traits<T>: T is not a function type" );
};

template< typename R, typename... Ts >
struct function_traits< R( Ts... ) >
{
  constexpr static const std::size_t arity = sizeof...( Ts );
  using result_type = R;
};

template< typename R, typename... Ts >
struct function_traits< R( Ts... ) const > : function_traits< R( Ts... ) > {};

template< typename R, typename... Ts >
struct function_traits< R( Ts... ) & > : function_traits< R( Ts... ) > {};

template< typename R, typename... Ts >
struct function_traits< R( Ts... ) const & > : function_traits< R( Ts... ) > {};

template< typename R, typename... Ts >
struct function_traits< R( Ts... ) && > : function_traits< R( Ts... ) > {};

template< typename R, typename... Ts >
struct function_traits< R( Ts... ) const && > : function_traits< R( Ts... ) > {};

这样,您可以轻松限制类中的参数数量:

template <typename Ret, typename T>
class MemberWrapper<Ret T::*>
{
  static_assert( function_traits<Ret>::arity <= 4,
                 "More than 4 arguments are not allowed" );
};

Live example

【讨论】:

  • R(Ts...) 是否匹配 cv 或 ref 限定的成员函数?
  • (不,它没有。但现在我想知道为什么 std::remove_cv 不删除那些 cv 限定符。)
  • @dyp 你是对的,它没有。你需要像this这样的专业。
  • @DanielFrey 这开始看起来像 std::mem_fn 重载集,这是我想要避免的。
  • @Pradhan 更新了答案。最后,您将需要提供一些重载,除非标准库将来会提供类似的东西。重要的是隔离此功能一次并在您的代码中重用它,这样就不会再遭受多次重载/特化。
【解决方案2】:

Boost Function Types 提供了大量的函数特征。此外,这个SO post 显示了示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 2017-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多