现在的位置: 首页 > 综合 > 正文

C++0x:如何获取lambda表达式的返回类型

2013年08月06日 ⁄ 综合 ⁄ 共 1429字 ⁄ 字号 评论关闭

最近看了老赵的博文,意识到lambda不仅仅提供了一个仿函数的语法糖,而在于能封装环境变量,从而更轻松的实现异步函数调用.

之前利用模板实现过异步函数调用,因为VS2008以前的C++不支持variadic templates和lambda,所以,其实现是用宏实现的0至N个参数的仿函数.因此,本次修改主要是保留以前的代码的基础上,增加lambda的支持.但在获取lambda的返回值的地方费了会儿时间,遂Google之,然后找到这个链接:

http://blog.csdn.net/zwvista/article/details/5531829

为了方便说明,摘抄其内容:

int f() { return 1;  }

struct X
{
	float operator () () const { return 2; }
	// If the following is enabled, program fails to compile
	// mostly because of ambiguity reasons.
	//double operator () (float i, double d) { return d*f; }
};

template <typename T> 
struct function_traits  
	: function_traits<decltype(&T::operator())>  // match X or lambda
{  
	// This generic template is instantiated on both the compilers as expected. 
}; 

template <typename R, typename C> 
struct function_traits<R (C::*)() const>  { // inherits from this one
	typedef R result_type; 
}; 

template <typename R> 
struct function_traits<R (*)()> { // match f
	typedef R result_type; 
}; 

template <typename F>
typename function_traits<F>::result_type
	foo(F f)
{
	return f();
}

int main(void)
{
	foo(f);
	foo(X());
	foo([](){ return 3; });
}

 

经过测试,这里面提到的方法行不通的,因为

&T::operator()不是T的静态函数.导致编译失败

联想到sizeof(function(x))并不实际调用函数,因此,我认为decltype(function(x))也不会实际调用函数.于是,将

&T::operator()

修改成

decltype(((T*)0)->operator()())

这就在VS2010中顺利编译通过.

 

完整代码如下:

template<typename LAMBDA>
struct function_traits
{
	typedef decltype(((LAMBDA*)0)->operator()()) return_type;
};
template<typename RET>
struct function_traits<RET(*)()>
{
	typedef RET return_type;   
};
template<typename RET,typename CLASS>
struct function_traits<RET(CLASS::*)() const>
{
	typedef RET return_type;   
};


 

抱歉!评论已关闭.