c++ - 如何找到模板函数返回的类型
问题描述
我需要找到这样的模板函数结果类型:
template<typename T>
T fun1(
T arg1,
result_fun<T>(some_fun)
);
或者类似的东西。所以在标准库中我找到了result_of(我也找到了invoke_result,它也不起作用)。所以我找到了找到这个函数语法的帖子。它适用于sipmle代码,但是......它不适用于指针......示例(它和 ideone 代码相等):
#include <iostream>
#include <type_traits>
using namespace std;
template <typename T>
T *some(T x){
return &x;
}
template<typename T>
void somestrange(T x, typename result_of<decltype(&some<decltype(x)>)(decltype(x))>::type z);
template<typename T>
void somestrange(T x, typename result_of<decltype(&some<decltype(x)>)(decltype(x))>::type z){
cout << is_same<decltype(x), int>() << endl
<< is_same<decltype(z), int *>();
}
int main(){
int x = 0;
int *z = nullptr;
somestrange(x, z);
return 0;
}
它会起作用,但如果模板接收指针......
#include <iostream>
#include <type_traits>
using namespace std;
template <typename T>
T **some(T *x){
return &x;
}
template<typename T>
void somestrange(T x, typename result_of<decltype(&some<decltype(x)>)(decltype(x))>::type z);
template<typename T>
void somestrange(T x, typename result_of<decltype(&some<decltype(x)>)(decltype(x))>::type z){
cout << is_same<decltype(x), int>() << endl
<< is_same<decltype(z), int *>();
}
int main(){
int *x = 0;
int **z = nullptr;
somestrange(x, z);
return 0;
}
编译会生气。所以我想我能做些什么。我创造了自己的轮回......所以我写了这样的东西:
#include <iostream>
#include <type_traits>
#include <utility>
#include <typeinfo>
using namespace std;
template<typename Fun, typename Arg>
inline auto myinvoke(Fun&& f, Arg&& arg)
-> decltype(forward<Fun>(f)(forward<Arg>(arg)))
{
return (forward<Fun>(f)(forward<Arg>(arg)));
}
template<typename Fun, typename Arg>
struct return_type {
using type = decltype(myinvoke(declval<Fun>(), declval<Arg>()));
};
template<typename Fun, typename Arg>
using return_type_t = typename return_type<Fun, Arg>::type;
template <typename T>
T *some(T x){
return &x;
}
template<typename T>
void somestrange(T x, return_type_t<decltype(some<T>), T> z);
template<typename T>
void somestrange(T x, return_type_t<decltype(some<T>), T> z){
cout << is_same<decltype(x), int>() << endl
<< is_same<decltype(z), int *>();
}
int main(){
int x = 0;
int *z = nullptr;
somestrange(x, z);
return 0;
}
但如果我在这里,你可以猜到它不起作用。你会是对的,因为它不适用于ptr,同样不能使用 result_of:
#include <iostream>
#include <type_traits>
#include <utility>
#include <typeinfo>
using namespace std;
template<typename Fun, typename Arg>
inline auto myinvoke(Fun && f, Arg&& arg)
-> decltype(forward<Fun>(f)(forward<Arg>(arg)))
{
return (forward<Fun>(f)(forward<Arg>(arg)));
}
template<typename Fun, typename Arg>
struct return_type {
using type = decltype(myinvoke(declval<Fun>(), declval<Arg>()));
};
template<typename Fun, typename Arg>
using return_type_t = typename return_type<Fun, Arg>::type;
template <typename T>
T **some(T *x){
return &x;
}
template<typename T>
void somestrange(T x, return_type_t<decltype(some<T>), T> z);
template<typename T>
void somestrange(T x, return_type_t<decltype(some<T>), T> z){
cout << is_same<decltype(x), int>() << endl
<< is_same<decltype(z), int *>();
}
int main(){
int *x = 0;
int **z = nullptr;
somestrange(x, z);
return 0;
}
那么我能用它做什么呢?有人知道我该如何解决这个问题(我只能使用 STL)?感谢您的回答
解决方案
和
int *x = 0;
int **z = nullptr;
somestrange(x, z);
和
template<typename T>
void somestrange(T x, return_type_t<decltype(some<T>), T> z);
T
将会int*
some<T>
期望T*
参数
所以改为
template<typename T>
void somestrange(T* x, return_type_t<decltype(some<T>), T*> z);
或者
template<typename T>
void somestrange(T* x, return_type_t<decltype(some<std::remove_pointer_t<T>>), T> z);
或者不明确指定模板,并允许扣除:
template<typename T>
void somestrange(T x, decltype(some(std::declval<T>())) z);
推荐阅读
- python - 整个屏幕上的鼠标释放事件
- python - 从文件夹中获取多个xml文件
- php - 如何制作一个在 Symfony 的每一页上执行的控制器?
- mysql - 使用 fk 连接来自两个表的数据
- google-sheets - 从 Google 电子表格接收通知或更新(例如 webhook)的正确方法是什么
- ubuntu-18.04 - Freeradius 服务不工作:进程:6181 ExecStartPre=/usr/sbin/freeradius $FREERADIUS_OPTIONS -Cxm -lstdout (code=exited, status=1/FAILURE)
- dart - 在扩展函数中获取具体类型
- c# - 如何在 C++ 中创建枚举类
- csv - 对 S3 文件内容实施严格的政策
- javascript - JavaScript RegEx 如何动态提取子字符串