使用Boost获取成员函数的数量和参数类型? (升压::function_traits)

发布于 2024-08-19 19:37:45 字数 1060 浏览 6 评论 0原文

对于普通的普通函数来说,它工作得很好。下面的代码工作得很好。它只打印应该的内容:

int __cdecl(int, char)
2
int,char

#include <boost/type_traits.hpp>
#include <boost/function.hpp>
#include <boost/typeof/std/utility.hpp>

#include <iostream>

using std::cout;
using std::endl;

int foo(int, char) {
 return 0;
}
int main() {
    typedef BOOST_TYPEOF(foo) foo_type;;
    typedef boost::function_traits<foo_type> function_traits;

    cout << typeid(foo_type).name() << endl;
    cout << function_traits::arity << endl;
    cout << typeid(function_traits::arg1_type).name() << ",";
    cout << typeid(function_traits::arg2_type).name() << endl;

    return 0;
}

那么,问题是,如果 foo 是类 bar 的成员函数,如何才能做到这一点?

struct bar {
    int foo(int, char) { return 0; }
};

我尝试过这些构造的无数组合: BOOST_TYPEOF_INCRMENT_REGISTRATION_GROUP() BOOST_TYPEOF_REGISTER_TYPE() boost::ref boost::remove_pointer boost::bind boost::mem_fn

等等,等等...没有乐趣。

It works just fine, for plain vanilla functions. The code below works just fine. It prints just what is should:

int __cdecl(int, char)
2
int,char

#include <boost/type_traits.hpp>
#include <boost/function.hpp>
#include <boost/typeof/std/utility.hpp>

#include <iostream>

using std::cout;
using std::endl;

int foo(int, char) {
 return 0;
}
int main() {
    typedef BOOST_TYPEOF(foo) foo_type;;
    typedef boost::function_traits<foo_type> function_traits;

    cout << typeid(foo_type).name() << endl;
    cout << function_traits::arity << endl;
    cout << typeid(function_traits::arg1_type).name() << ",";
    cout << typeid(function_traits::arg2_type).name() << endl;

    return 0;
}

So, the question is, how can one do this if foo is a member function of class bar?

struct bar {
    int foo(int, char) { return 0; }
};

I have tried countless combinations of these constructs: BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() BOOST_TYPEOF_REGISTER_TYPE() boost::ref boost::remove_pointer boost::bind boost::mem_fn

etc., etc... No joy.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱的十字路口 2024-08-26 19:37:45

Boost 函数类型 可能是自然的解决方案:

#include <boost/function_types/function_type.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/function_arity.hpp>
#include <boost/typeof/std/utility.hpp>
#include <boost/typeof/typeof.hpp>
#include <iostream>

struct bar {
    int foo(int, char) { return 0; }
};

int main() {

    typedef BOOST_TYPEOF(&bar::foo) foo_type;

    std::cout << typeid(foo_type).name() << std::endl;
    std::cout << boost::function_types::function_arity<foo_type>::value << std::endl;
    std::cout << typeid(boost::mpl::at_c<boost::function_types::parameter_types<foo_type>,1>::type).name() << ",";
    std::cout << typeid(boost::mpl::at_c<boost::function_types::parameter_types<foo_type>,2>::type).name() << ",";

    return 0;
}

Boost Function Types would probably be the natural solution:

#include <boost/function_types/function_type.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/function_arity.hpp>
#include <boost/typeof/std/utility.hpp>
#include <boost/typeof/typeof.hpp>
#include <iostream>

struct bar {
    int foo(int, char) { return 0; }
};

int main() {

    typedef BOOST_TYPEOF(&bar::foo) foo_type;

    std::cout << typeid(foo_type).name() << std::endl;
    std::cout << boost::function_types::function_arity<foo_type>::value << std::endl;
    std::cout << typeid(boost::mpl::at_c<boost::function_types::parameter_types<foo_type>,1>::type).name() << ",";
    std::cout << typeid(boost::mpl::at_c<boost::function_types::parameter_types<foo_type>,2>::type).name() << ",";

    return 0;
}
粉红×色少女 2024-08-26 19:37:45

这可以通过更新的 boost lib 来完成(可调用特征,额外的好处:它也可以与 lambda 一起使用)。

我还添加了另一个带有人类可读输出的打印输出,尽管不确定问题是否需要它。

#include <boost/mp11.hpp>
#include <boost/callable_traits.hpp>
#include <iostream>
#include <type_traits>
#include <boost/type_index.hpp>
using namespace std;
using namespace boost::mp11;
using namespace boost::typeindex;
namespace ct = boost::callable_traits;

struct bar {
    int foo(int, char) { return 0; }
};

int main() {

    using Fn = decltype(&bar::foo);
    cout << typeid(Fn).name() << endl;
    cout << tuple_size<ct::args_t<Fn>>::value << endl; // includes implicit this
    cout << typeid(mp_at_c<ct::args_t<Fn>,0>).name() << ",";
    cout << typeid(mp_at_c<ct::args_t<Fn>,1>).name()  << endl;
    cout << "Human readable" << endl;
    cout << type_id<Fn>().pretty_name() << endl;
    cout << tuple_size<ct::args_t<Fn>>::value << endl; // includes implicit this
    cout << type_id<mp_at_c<ct::args_t<Fn>,0>>().pretty_name() << ",";
    cout << type_id<mp_at_c<ct::args_t<Fn>,1>>().pretty_name() << endl;
    return 0;
}

海湾合作委员会输出:

M3barFiicE

3

3bar,我

人类可读

int (bar::*)(int, char)

3

酒吧,整数

This can be done with newer boost lib(callable traits, bonus: it works with lambdas also).

I have also added the another printout with a human readable output, although not sure if the question demands it.

#include <boost/mp11.hpp>
#include <boost/callable_traits.hpp>
#include <iostream>
#include <type_traits>
#include <boost/type_index.hpp>
using namespace std;
using namespace boost::mp11;
using namespace boost::typeindex;
namespace ct = boost::callable_traits;

struct bar {
    int foo(int, char) { return 0; }
};

int main() {

    using Fn = decltype(&bar::foo);
    cout << typeid(Fn).name() << endl;
    cout << tuple_size<ct::args_t<Fn>>::value << endl; // includes implicit this
    cout << typeid(mp_at_c<ct::args_t<Fn>,0>).name() << ",";
    cout << typeid(mp_at_c<ct::args_t<Fn>,1>).name()  << endl;
    cout << "Human readable" << endl;
    cout << type_id<Fn>().pretty_name() << endl;
    cout << tuple_size<ct::args_t<Fn>>::value << endl; // includes implicit this
    cout << type_id<mp_at_c<ct::args_t<Fn>,0>>().pretty_name() << ",";
    cout << type_id<mp_at_c<ct::args_t<Fn>,1>>().pretty_name() << endl;
    return 0;
}

gcc output:

M3barFiicE

3

3bar,i

Human readable

int (bar::*)(int, char)

3

bar,int

生活了然无味 2024-08-26 19:37:45

科内尔·基西莱维奇(Kornel Kisielewicz)做到了。这是与测试消息分开的解决方案。

#include <boost/function_types/function_type.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/function_arity.hpp>
#include <boost/typeof/std/utility.hpp>
#include <iostream>

struct bar {
    int foo(int, char) { return 0; }
};

int main() {

    typedef BOOST_TYPEOF(&bar::foo) 
        foo_type;
    int arity = boost::function_types::function_arity<foo_type>::value;
    typedef boost::mpl::at_c<boost::function_types::parameter_types<foo_type>,1>::type
        arg1;
    typedef boost::mpl::at_c<boost::function_types::parameter_types<foo_type>,2>::type
        arg2;

    std::cout << typeid(foo_type).name() << std::endl;
    std::cout << arity << std::endl;
    std::cout << typeid(arg1).name() << ",";
    std::cout << typeid(arg2).name() << std::endl;
    return 0;
}

Kornel Kisielewicz nailed it. Here it is with the solution separated from the test-messages.

#include <boost/function_types/function_type.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/function_arity.hpp>
#include <boost/typeof/std/utility.hpp>
#include <iostream>

struct bar {
    int foo(int, char) { return 0; }
};

int main() {

    typedef BOOST_TYPEOF(&bar::foo) 
        foo_type;
    int arity = boost::function_types::function_arity<foo_type>::value;
    typedef boost::mpl::at_c<boost::function_types::parameter_types<foo_type>,1>::type
        arg1;
    typedef boost::mpl::at_c<boost::function_types::parameter_types<foo_type>,2>::type
        arg2;

    std::cout << typeid(foo_type).name() << std::endl;
    std::cout << arity << std::endl;
    std::cout << typeid(arg1).name() << ",";
    std::cout << typeid(arg2).name() << std::endl;
    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文