C++ std::result_of, std::invoke_result <type_traits> (tcy)

1.1.函数:				
	std::result_of                              (removed in C++20)			
	template< class F, class... ArgTypes>		(since C++17)	
	class invoke_result;			
				
	template< class F, class... ArgTypes>	-2	(since C++17)	
	using invoke_result_t = typename invoke_result<F, ArgTypes...>::type;			
				
1.2.用途:				
	推导在编译时INVOKE表达式的返回类型			

1.3.说明:				
	类F任何完整类型ArgTypes,未知范围数组或(可能是cv限定)void				
	为此页面上描述的任何模板添加专门化的程序的行为是未定义的				
				
1.4.注意:
	1)F(Args...)以Args.为参数类型,F返回类型							
	2)F 不能是函数类型或数组类型(但可以是对它们的引用)						
	3)如果任何一Args具有“数组T”类型或函数类型T,它会自动调整为T*;				
	4)无论是F还是任何Args.都不能是抽象类类型
	5)如果Args中的任何一个参数有一顶级cv-限定符会被丢弃;						
	6)没有一个Args参数是void
							
    //为避免这些怪癖,result_of通常将引用类型与F和一起使用Args...								
	template<class F, class... Args>				
	std::result_of_t<F&&(Args&&...)> // 替代result_of_t<F(Args...)>, 错误				
	my_invoke(F&& f, Args&&... args) {...}	
2.实例:
	
	#include <assert.h>
	#include <type_traits>				
	#include <iostream>				

	using namespace std;

	struct A {
		double operator()(char, int&) {}
		float operator()(int) { return 1.0; }
	};

	int func(const int& x){	return x;}

	struct CallObject {

		inline CallObject(const int& val) {}

		template<typename T>
		inline T operator()(const T& x)noexcept{return x;}
	};

	struct CObject {
		int data;

		inline CObject(const int& val) :data(val) {}
		inline int getData(const int& x)noexcept{return data+x;}
	};

	template<class T>
	typename std::result_of<T(int)>::type f(T& t)
	{
		std::cout << "overload of f for callable T\n";
		return t(0);
	}

	template<class T, class U>
	int f(U u)
	{
		std::cout << "overload of f for non-callable T\n";
		return u;
	}
int main() {
		//普通函数:
		static_assert(is_same<int(const int&), decltype(func)>::value, ""); //注意func并没有转为指针
		static_assert(is_same<int(*)(const int&), decltype(&func)>::value, "");
		static_assert(is_same<int(&)(const int&), decltype(func)&>::value, "");

		static_assert((is_same<int(*)(const int&), //注意func转为指针
			invoke_result<decltype(&func)(const int&), const int&>::type>::value) == true);

		cout << typeid(invoke_result<decltype(func), const int&>::type).name() << endl; //int
		cout << typeid(invoke_result<decltype(func)&, const int&>::type).name() << endl;//int
		cout << typeid(invoke_result<decltype(&func), const int&>::type).name() << endl;//int
		cout << typeid(invoke_result<decltype(func)*, const int&>::type).name() << endl; //int

		cout << typeid(invoke_result<decltype(func)&(const int&), const int&>::type).name() << endl;//int __cdecl(int const & __ptr64)
		cout << typeid(invoke_result<decltype(func)*(const int&), const int&>::type).name() << endl; //int __cdecl(int const & __ptr64)

		cout << typeid(invoke_result<CallObject, const int&>::type).name() << endl;//int
		cout << typeid(invoke_result<CallObject, float>::type).name() << endl;//float

		//decltype(declval<CObject>().getData(declval<const int&>()));//错误?不明白请高手补充

		cout << is_same<int, decltype(declval<CObject>().data)>::value << endl;
		cout << typeid(invoke_result<decltype(&CObject::getData), CObject, const int&>::type).name() << endl;//int

		//用char和int&参数调用A的结果是double 	
		std::result_of<A(char, int&)>::type x1 = 3.14; // double x1;			
		static_assert(std::is_same<decltype(x1), double>::value, "");

		// std :: invoke_result使用不同的语法(不带括号) 	
		std::invoke_result<A, char, int&>::type x2 = 3.14;// double x1;
		static_assert(std::is_same<decltype(x2), double>::value, "");

		//用int参数调用A的结果是float 	
		std::result_of<A(int)>::type x3 = float(3.14); // float	x3;			
		static_assert(std::is_same<decltype(x3), float>::value, "");

		std::invoke_result<A, int>::type x31 = float(3.14);// float x1;
		static_assert(std::is_same<decltype(x31), float>::value, "");

		// result_of可以与指向成员函数的指针一起使用,如下所示:	
		struct B { double Func(char, int&); };
		std::result_of<decltype(&B::Func)(B, char, int&)>::type x4 = 3.14;
		static_assert(std::is_same<decltype(x4), double>::value, "");

		cout << typeid(invoke_result<decltype(&B::Func), B, char, int&>::type).name() << endl;//double

		// B++11错误; calls the non-callable overload in B++14	
		f<B>(1);// 输出overload of f for non-callable T			
	}

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
In file included from /home/yhdr/2-test-2023-06_v3/sent.h:24:0, from /home/yhdr/2-test-2023-06_v3/sent.cpp:1: /usr/include/c++/7/thread: In instantiation of ‘struct std::thread::_Invoker<std::tuple<void (*)(double*, double&, double&, double&, double&, double&), double**, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double> > >’: /usr/include/c++/7/thread:127:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(double*, double&, double&, double&, double&, double&); _Args = {double**, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>}]’ /home/yhdr/2-test-2023-06_v3/sent.cpp:18:153: required from here /usr/include/c++/7/thread:240:2: error: no matching function for call to ‘std::thread::_Invoker<std::tuple<void (*)(double*, double&, double&, double&, double&, double&), double**, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double> > >::_M_invoke(std::thread::_Invoker<std::tuple<void (*)(double*, double&, double&, double&, double&, double&), double**, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double> > >::_Indices)’ operator()() ^~~~~~~~ /usr/include/c++/7/thread:231:4: note: candidate: template<long unsigned int ..._Ind> decltype (std::__invoke((_S_declval<_Ind>)()...)) std::thread::_Invoker<_Tuple>::_M_invoke(std::_Index_tuple<_Ind ...>) [with long unsigned int ..._Ind = {_Ind ...}; _Tuple = std::tuple<void (*)(double*, double&, double&, double&, double&, double&), double**, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double> >] _M_invoke(_Index_tuple<_Ind...>)
06-07

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值