c++ - C++03中如何判断函数是否返回引用?

标签 c++ reference

在 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, yields_lvalue_1<foo, 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), long>::result);
    print(false, yields_lvalue_1<foo(&)(int), short>::result);
}

关于c++ - C++03中如何判断函数是否返回引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20024092/

相关文章:

c++ - 不理解静态 boolean 行为

c++ - 异步事件通知的思路

c++ - 通过引用捕获对象

java - 获取指向对象的所有引用变量

c++ - 任何函数都可以是删除函数吗?

c++ - 如何在 C++ 中终止进程,只知道其名称的一部分

关于运算符重载和内存泄漏的 C++ 引用

c++ - 转换运算符中的段错误(对成员的引用)

c++ - 如何写一个n元否定器?

java - 对象引用设置为 null 后会发生什么