【问题标题】:C++: Extracting parameter type from static function in structC++:从结构中的静态函数中提取参数类型
【发布时间】:2018-11-29 17:20:05
【问题描述】:

假设我有这样的事情:

template<typename T, typename R>
struct MyStruct {
    static R myfunc(T);
};

struct MyStructInst: S<int, double> {
    static double myfunc(int i) { return i; }
};

然后,我有一个采用M 的模板,我将假设该类型具有带有一个参数的静态myfunc 函数(例如MyStructInst)。我要提取myfunc的参数类型和结果类型:

template<typename M,
    typename ParamType = ???,
    typename ResultType = decltype(declval(M::myfunc))> // I think this works?
struct MyStruct2 {
    ...
};

获取ParamType 的最简单方法是什么?

【问题讨论】:

    标签: c++ templates c++17 template-meta-programming template-argument-deduction


    【解决方案1】:

    怎么样

    template <typename R, typename A0, typename ... As>
    constexpr A0 firstArg (R(*)(A0, As...));
    
    template <typename M,
              typename PT = decltype(firstArg(&M::myfunc)),
              typename RT = decltype(M::myfunc(std::declval<PT>()))>
    struct MyStruct2 
     { };
    

    ?

    我的意思是...如果您声明(不需要实现它,因为仅在 decltype() 内部使用,所以只有返回的类型很重要)接收函数类型的函数(我记得一个指针静态方法就像一个指向传统函数的指针)接收一个或多个参数并返回第一个参数的类型

    template <typename R, typename A0, typename ... As>
    constexpr A0 firstArg (R(*)(A0, As...));
    

    给定一个模板类型名M,你可以获得myFunc()方法的第一个参数(如果有的话)

    typename PT = decltype(firstArg(&M::myfunc))
    

    给定PT(第一个类型参数的类型),您可以简单地模拟(在decltype() 内,使用std::declval())使用PT 类型的对象调用myfunc() 来获得返回类型

    typename RT = decltype(M::myfunc(std::declval<PT>()))
    

    以下是完整的编译示例

    #include <string>
    #include <type_traits>
    
    template <typename T, typename R>
    struct MyStruct
     { static R myfunc(T); };
    
    struct MyStructInst 
     { static double myfunc(int i) { return i; } };
    
    template <typename R, typename A0, typename ... As>
    constexpr A0 firstArg (R(*)(A0, As...));
    
    template <typename M,
              typename PT = decltype(firstArg(&M::myfunc)),
              typename RT = decltype(M::myfunc(std::declval<PT>()))>
    struct MyStruct2 
     { using type1 = PT; using type2 = RT; };
    
    int main ()
     {
       static_assert( std::is_same<int,
          typename MyStruct2<MyStructInst>::type1>{}, "!");
       static_assert( std::is_same<double,
          typename MyStruct2<MyStructInst>::type2>{}, "!");
       static_assert( std::is_same<long,
          typename MyStruct2<MyStruct<long, std::string>>::type1>{}, "!");
       static_assert( std::is_same<std::string,
          typename MyStruct2<MyStruct<long, std::string>>::type2>{}, "!");
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-23
      • 1970-01-01
      • 2018-06-17
      • 2013-11-29
      • 2017-08-25
      • 2011-10-07
      • 2023-03-14
      • 2021-10-06
      相关资源
      最近更新 更多