C++:从结构中的静态函数中提取参数类型

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

假设我有这样的东西:

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的最简单方法是什么?

最佳答案

怎么样

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() 中使用,所以只有返回的类型很重要)接收函数的函数类型(我记得指向 static 方法的指针就像指向传统函数的指针)接收一个或多个参数并返回第一个参数的类型

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>{}, "!");
 }

关于C++:从结构中的静态函数中提取参数类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53544408/

相关文章:

c++ - reference_wrapper : make_pair VS Class Template Argument Deduction (CTAD)

c++ - 如何在 OpenCV 中导入带有展平层的 TensorFlow 模型?

c++ - 与C++和汇编相关,什么是ebp+8?

templates - 为什么enable_if不能用于特殊参数?

wpf - 重用内置 WPF 样式

c++ - 奇怪的重复模板模式和虚拟继承

c++ - 为什么c++11标准库中没有std::clear

c++ - 从可执行文件中调用成员函数

c++ - new(std::nothrow) int[n] 抛出异常

c++ - 依赖于规则的模板成员变量