Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 确定函子的参数和结果类型_C++_Functor_Sfinae - Fatal编程技术网

C++ 确定函子的参数和结果类型

C++ 确定函子的参数和结果类型,c++,functor,sfinae,C++,Functor,Sfinae,如何测试functor是否是一个可调用对象,它引用int并返回bool template<typename functor> void foo(functor f) { static_assert('functor == bool (int&)', "error message"); int x = -1; if (f(x)) std::cout << x << std::endl; } bool bar(i

如何测试functor是否是一个可调用对象,它引用int并返回bool

template<typename functor>
void foo(functor f)
{
    static_assert('functor == bool (int&)', "error message");

    int x = -1;
    if (f(x))
        std::cout << x << std::endl;
}

bool bar(int& x)
{
    x = 4711;
    return true;
}

struct other
{
    bool operator()(int& x)
    {
        x = 815;
        return true;
    }
};
模板
void foo(函子f)
{
静态断言('functor==bool(int&'),“错误消息”);
int x=-1;
if(f(x))

std::cout如果您的编译器支持它,您可以使用头
is_函数

在我看来,您并不是真的想检查函子的签名,而是想限制用户可以传入的内容,首先:

如果您有权访问
std::function
,则可以执行以下操作:

void foo(const std::function<bool(int&)>& f)
void foo(const std::function&f)

我假设C++11解决方案不被排除在外

我也会假设OP相信他所希望的是正确的 检测具有签名的函数或函子
bool(int&)
std::function
,如Dave所建议:

void foo(const std::function<bool(int&)>& f);
是这样一个对象,将其视为“可调用对象”似乎有些牵强 它引用int并返回bool。“

事实上,我们希望测试类类型的函数和对象 表示静脉中的SFINAE类模板:

template<typename T>
struct is_predicate_of_ref_to_int_type { ... };
使用GCC4.7.2或Clang3.2构建,具有预期的输出

这里有一个警告。任何重载
operator()
的函子类型都将失败 测试,例如

struct bar
{
    bool operator()(int & i) { ... }
    bool operator()(int & i, int & j) { ... }
};
即使其中一个过载令人满意,由于标准
获取重载成员函数地址的限制。

是否有可用的c++11编译器?是否可以使用boost类型特征库?是否要区分
other::operator()
bar()
?还是只想知道
functor f
是否属于
bool(int&)类型
?你的意思是:(从维基百科复制并黑客攻击)?
#include <type_traits>

template<class T>
struct is_predicate_of_ref_to_int_type {
    // SFINAE operator-has-correct-sig- :)
    template<class A>
    static auto test(bool (A::*)(int &)) -> std::true_type;

    // SFINAE operator-exists :)
    template <class A> 
    static auto test(decltype(&A::operator()),void *) ->
        // So the operator exists. Has it the correct sig? 
        decltype(test(&A::operator()));

    // SFINAE failure :(
    template<class A>
    static auto test(...) -> std::false_type;

    // This will be either `std::true_type` or `std::false_type`
    typedef decltype(test<T>(0,0)) type;

    static const bool value = type::value;

};

template<typename T>
bool is_predicate_of_ref_to_int(T const & t) {
    return is_predicate_of_ref_to_int_type<T>::value;
}

bool is_predicate_of_ref_to_int(bool (function)(int &)) {
    return true;
}

// Testing...

struct passing_class_0
{
    bool operator()(int & i) {
        return i > 0;
    }
};

struct failing_class_0
{
    bool operator()(int i) {
        return i > 0;
    }
};

struct failing_class_1
{
    bool operator()(int & i, int & j) {
        return i > j;
    }
}   

struct failing_class_2{};


bool passing_function_0(int & i) {
    return i > 0;
}

bool failing_function_0(int i) {
    return i > 0;
}

int failing_function_1(int & i) {
    return i;
}

void failing_function_2(){}

#include <iostream>

using namespace std;


int main()
{
    passing_class_0 pc0;
    failing_class_0 fc0;
    failing_class_1 fc1;
    failing_class_2 fc2;

    cout << "Expecting pass..." << endl;
    cout << is_predicate_of_ref_to_int(pc0) << endl;
    cout << is_predicate_of_ref_to_int(passing_function_0) << endl;
    cout << "Expecting fail..." << endl;
    cout << is_predicate_of_ref_to_int(fc0) << endl;
    cout << is_predicate_of_ref_to_int(fc1) << endl;
    cout << is_predicate_of_ref_to_int(fc2) << endl;
    cout << is_predicate_of_ref_to_int(failing_function_0) << endl;
    cout << is_predicate_of_ref_to_int(failing_function_1) << endl;
    cout << is_predicate_of_ref_to_int(failing_function_2) << endl;
    cout << is_predicate_of_ref_to_int(failing_function_2) << endl;
    cout << is_predicate_of_ref_to_int(1L) << endl; 
    return 0; 
}
struct bar
{
    bool operator()(int & i) { ... }
    bool operator()(int & i, int & j) { ... }
};