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

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

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

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

那我该如何实现is_reference?

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

解决方法

这是一个基于SFINAE的解决方案,用于检查函数调用表达式是否产生左值:
#include <boost/type_traits.hpp>
#include <boost/utility.hpp>
#include <cstddef>

// Func: function (object/pointer/reference) type
// Arg0: type of the first argument to use (for overload resolution)
template<class Func,class Arg0>
struct yields_lvalue_1 // with one argument
{
    typedef char yes[1];
    typedef char no[2];

    // decay possible function types
    typedef typename boost::decay<Func>::type F_decayed;

    // a type whose constructor can take any lvalue expression
    struct Any
    {
        template<class T>
        Any(T&);
    };

    // SFINAE-test: if `Any(....)` is well-formed,this overload of `test` is
    // viable
    template<class T>
    static yes& test(boost::integral_constant<std::size_t,sizeof(Any( boost::declval<T>()(boost::declval<Arg0>()) ))>*);
    // fall-back
    template<class T>
    static no&  test(...);

    // perform test
    static bool const result = sizeof(test<F_decayed>(0)) == sizeof(yes);
};

一些示例性功能对象:

struct foo
{
    bool& operator()(int);
    bool operator()(double);
};

struct bar
{
    template<class T>
    double operator()(T);
};

用法示例:

#include <iostream>
#include <iomanip>

void print(bool expect,bool result)
{
    std::cout << "expect: "<<std::setw(5)<<expect<<" -- result: "<<result<<"\n";
}

int main()
{
    std::cout << std::boolalpha;
    print(true,yields_lvalue_1<foo,int>   ::result);
    print(false,double>::result);
    print(false,yields_lvalue_1<bar,int>   ::result);
    print(true,yields_lvalue_1<foo&(*)(long),int>::result);
    print(false,yields_lvalue_1<void(*)(int),short>::result);
    print(true,yields_lvalue_1<bool&(short),long>::result);
    print(false,yields_lvalue_1<void(float),int>::result);
    print(true,yields_lvalue_1<char&(&)(bool),yields_lvalue_1<foo(&)(int),short>::result);
}

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