如何使用 BOOST BinaryFunction 概念?

How do I use BOOST BinaryFunction concept?

没有我能找到的文档,也没有我在进行 google 搜索时看到的任何相关内容:

我有一个函数,我想生成一个签名:

(void)(int,int)

所以当我 运行 这两个函数为:

void dosomething(int x, int y);
void dosomethingwront(float x, float y);

通过:

// Should succeed
boost::BinaryFunction<dosomething,void,int,int>
// Should fail
boost::BinaryFunction<dosomethingwrong,void,int,int>

编译失败,因为它不喜欢第一个参数类型。不幸的是,我不确定他们的文档中的 <class Func,...> 是什么意思。如果我有这两个功能,我该如何测试这些概念?

谢谢

模板参数必须是类型。 您可以使用 decltype((dosomething))。请注意,您的概念不会因 dosomethingwront 而失败,因为 int 可转换为 float 并且该概念检查二进制函数是否 callable int,而不是检查函数签名。

#include <boost/concept_check.hpp>

void dosomething(int x, int y);
void dosomethingwront(float x, float y);

int main() {
    BOOST_CONCEPT_ASSERT((boost::BinaryFunction<decltype((dosomething)),void,int,int>));
    BOOST_CONCEPT_ASSERT((boost::BinaryFunction<decltype((dosomethingwront)),void,int,int>));
}

如果你想根据函数参数严格检查这个概念,你可以使用基于显式模板特化的类型特征。以下并未穷尽所有可能的 const 和 volatile 限定条件。

#include <iostream>
#include <type_traits>

template <typename F>
struct is_void_int_int : std::false_type {};

// Free function
template <>
struct is_void_int_int<void(int, int)> : std::true_type {};

// Pointer to function
template <>
struct is_void_int_int<void (*)(int, int)> : std::true_type {};

// Reference to function
template <>
struct is_void_int_int<void (&)(int, int)> : std::true_type {};

// Pointer to member function
template <typename C>
struct is_void_int_int<void (C::*)(int, int)> : std::true_type {};

void dosomething(int x, int y);
void dosomethingwront(float x, float y);

struct A {
    void operator()(int, int) {}
};

struct B {
    void bar(int, int) {}
};

int main() {
    static_assert(is_void_int_int<decltype(dosomething)>::value, "!");
    static_assert(is_void_int_int<decltype((dosomething))>::value, "!");
    static_assert(is_void_int_int<decltype(&dosomething)>::value, "!");
    static_assert(is_void_int_int<decltype(&A::operator())>::value, "!");
    static_assert(is_void_int_int<decltype(&B::bar)>::value, "!");
  //static_assert(is_void_int_int<decltype(dosomethingwront)>::value, "!"); // BOOM!
}