如何确定函数是否在C 03中返回引用?

前端之家收集整理的这篇文章主要介绍了如何确定函数是否在C 03中返回引用?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在C 11之前的版本中,当使用特定参数调用时,如何确定给定函数是否返回引用?

例如,如果代码如下所示:

  1. template<class F>
  2. bool returns_reference(F f) { return is_reference(f(5)); }

那我该如何实现is_reference?

请注意,f也可能是一个仿函数,它的operator()可能有多个重载 – 我只关心实际通过我的参数调用的重载.

解决方法

这是一个基于SFINAE的解决方案,用于检查函数调用表达式是否产生左值:
  1. #include <boost/type_traits.hpp>
  2. #include <boost/utility.hpp>
  3. #include <cstddef>
  4.  
  5. // Func: function (object/pointer/reference) type
  6. // Arg0: type of the first argument to use (for overload resolution)
  7. template<class Func,class Arg0>
  8. struct yields_lvalue_1 // with one argument
  9. {
  10. typedef char yes[1];
  11. typedef char no[2];
  12.  
  13. // decay possible function types
  14. typedef typename boost::decay<Func>::type F_decayed;
  15.  
  16. // a type whose constructor can take any lvalue expression
  17. struct Any
  18. {
  19. template<class T>
  20. Any(T&);
  21. };
  22.  
  23. // SFINAE-test: if `Any(....)` is well-formed,this overload of `test` is
  24. // viable
  25. template<class T>
  26. static yes& test(boost::integral_constant<std::size_t,sizeof(Any( boost::declval<T>()(boost::declval<Arg0>()) ))>*);
  27. // fall-back
  28. template<class T>
  29. static no& test(...);
  30.  
  31. // perform test
  32. static bool const result = sizeof(test<F_decayed>(0)) == sizeof(yes);
  33. };

一些示例性功能对象:

  1. struct foo
  2. {
  3. bool& operator()(int);
  4. bool operator()(double);
  5. };
  6.  
  7. struct bar
  8. {
  9. template<class T>
  10. double operator()(T);
  11. };

用法示例:

  1. #include <iostream>
  2. #include <iomanip>
  3.  
  4. void print(bool expect,bool result)
  5. {
  6. std::cout << "expect: "<<std::setw(5)<<expect<<" -- result: "<<result<<"\n";
  7. }
  8.  
  9. int main()
  10. {
  11. std::cout << std::boolalpha;
  12. print(true,yields_lvalue_1<foo,int> ::result);
  13. print(false,double>::result);
  14. print(false,yields_lvalue_1<bar,int> ::result);
  15. print(true,yields_lvalue_1<foo&(*)(long),int>::result);
  16. print(false,yields_lvalue_1<void(*)(int),short>::result);
  17. print(true,yields_lvalue_1<bool&(short),long>::result);
  18. print(false,yields_lvalue_1<void(float),int>::result);
  19. print(true,yields_lvalue_1<char&(&)(bool),yields_lvalue_1<foo(&)(int),short>::result);
  20. }

猜你在找的C&C++相关文章