【问题标题】:How to grab the argument and return types from a std::function with cv and reference qualifiers?如何使用 cv 和引用限定符从 std::function 中获取参数和返回类型?
【发布时间】:2015-09-09 19:08:55
【问题描述】:

有没有一种从std::function 获取参数和返回类型的好方法,这样我们也可以返回 cv 和引用限定符?这部分与之前的问题here 有关。无论如何,使用答案中的代码,我们有以下示例:

#include <functional>
#include <iostream>

template<typename T> 
struct function_traits;

template<typename R, typename ...Args> 
struct function_traits<std::function<R(Args...)>> {
    static const size_t nargs = sizeof...(Args);

    typedef R result_type;

    template <size_t i>
    struct arg {
        typedef typename std::tuple_element<i, std::tuple<Args...>>::type
            type;
    };
};

template <typename T>
void foo(T const & f) {
    typedef function_traits <T> stuff;
    std::cout <<
        typeid(typename function_traits <T>::result_type).name()
        << std::endl;
    std::cout <<
        typeid(typename function_traits <T>::template arg<0>::type).name()
        << std::endl;
    std::cout << typeid(T).name() << std::endl;
}

int main() {
    std::cout << "Function: f" << std::endl;
    auto f = [](double x) { return x+1.;};
    foo <std::function<double(double)>> (f);

    std::cout << std::endl << "Function: g" << std::endl;
    auto g = [](double const & x) { return x+1.;};
    foo <std::function<double(double const &)>> (g);
}

现在,使用 c++filt,我们看到 f 的类型是 std::function&lt;double (double)&gt;g 的类型是 std::function&lt;double (double const&amp;)&gt;。但是,结构function_traits 报告参数类型是相同的,但事实并非如此。基本上,const&amp; 被剥离了g 的参数类型。有没有办法解决这个问题,以便保留const&amp;

【问题讨论】:

    标签: c++ c++11 c++14


    【解决方案1】:

    const 和引用被 typeid 剥离,而不是 function_traits。尝试添加

    std::cout << std::boolalpha << std::is_same<double,
        typename function_traits<T>::template arg<0>::type>::value  << std::endl;
    std::cout << std::boolalpha << std::is_same<const double&,
        typename function_traits<T>::template arg<0>::type>::value << std::endl;
    

    发送至您的foo,您将看到预期值。

    【讨论】:

    • 谢谢!顺便说一句,有没有办法在不使用 is_same 的情况下打印出 cv 限定符?基本上,保留所有限定符的typeid 版本。
    • 一种快速的方法是 typeid(wrap&lt;T&gt;) 并忽略输出中的 wrap 部分。
    • 感谢您的提示。除非我遗漏了什么并且万一其他人尝试这样做,否则这个技巧需要定义 template &lt;typename T&gt; struct wrap{};。然后,我们看到类似:wrap&lt;double const&amp;&gt; out of c++filt.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 2016-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多