How to determine the type of a function parameter given the type of argument passed to it?

后端 未结 3 2233
借酒劲吻你
借酒劲吻你 2021-02-19 11:31

I need a type trait which will report the type of a functor\'s operator() parameter given the type of the functor and the type of an argument passed to it. Basical

3条回答
  •  不知归路
    2021-02-19 12:19

    I am afraid that this is not exactly possible without help from your client.

    TL;DR: unit test fail (grrr gcc).

    The general case of your question is this functor:

    struct Functor {
      template 
      typename std::enable_if::value>::type
      operator()(T t) const;
    
      void operator(double d) const;
    };
    

    It combines the two main issues here:

    1. If there is an overload, then taking &F::operator() requires a static_cast to a given type to disambiguate which overload should be used
    2. Templates (and arbitrary conditions to express them) cannot be succintly expressed as typedefs

    Therefore, the client (Functor here) need to provide additional hooks for you if you truly wish to get this type. And without decltype I don't see how to get it (note, gcc provides typeof as an extension in C++03).

    Getting the client to give us hints:

    // 1. Make use of the return value:
    struct Functor {
      template 
      typename std::enable_if::value, T>::type
      operator()(T t) const;
    
      double operator(double d) const;
    };
    
    // 2. Double up the work (but leave the return value as is)
    struct Functor {
      template 
      static typename std::enable_if::value, T>::type Select(T);
    
      static double Select(T);
    
      template 
      typename std::enable_if::value>::type
      operator()(T t) const;
    
      void operator(double d) const;
    };
    

    Let's say we go for the second case (leaving the return value free for another use).

    template 
    struct parameter {
      static T t;
      typedef decltype(F::Select(t)) type;
    };
    

    In C++03, replace decltype by typeof with gcc.

    I don't see a way to forego decltype. sizeof does provides an unevaluated context but it does not seem to help much here.

    Unit Tests Here.

    Unfortunately, there is a gcc bug it seems with the references, and float& gets reduced to float (and any other reference really), the bug remains with decltype so it's just a buggy implementation :/ Clang 3.0 has no problem with the C++11 version (decltype) but does not implement typeof I think.

    This can be worked around by requiring the client to use a ref class instead, and then unwrapping it. Just a bit more burden...

提交回复
热议问题