【问题标题】:reference to function std::get<1> in tuple header元组标头中对函数 std::get<1> 的引用
【发布时间】:2010-10-25 18:12:12
【问题描述】:

如何获得对特定元组实例的“get”函数的引用?

下面给出了我最好的尝试,但不能针对 g++4.5.1 进行编译

#include <tuple>
#include <string>

typedef std::tuple<int,std::string> Tuple;
auto t=(std::string& (Tuple&))(std::get<1,Tuple>);

编译错误是:

a.cc:5: error: invalid cast to function type ‘std::string&(Tuple&)’ 
a.cc:5: error: unable to deduce ‘auto’ from ‘<expression error>’

我想将函数引用用作某些 stl 算法的输入。实际上,我对这对我来说似乎是多么的不平凡感到有点惊讶。

【问题讨论】:

    标签: c++ c++11 tuples


    【解决方案1】:

    我想你想要:

    namespace detail
    {
        template <std::size_t I, typename... Types>
        decltype(&std::get<I, Types...>) get_function(std::tuple<Types...>*)
        {
            return &std::get<I, Types...>;
        }
    }
    
    template <std::size_t I, typename Tuple>
    decltype(detail::get_function<I>((Tuple*)nullptr)) get_function()
    {
        return detail::get_function<I>((Tuple*)nullptr);
    }
    
    auto t = get_function<I, Tuple>();
    

    有点丑。当然有更好的方法,但我现在只有这些。

    【讨论】:

    • 我希望有一个单行,但我知道这应该如何工作。 gcc-4.5.1 抱怨 nullptr 以及之后的类型推导。稍后我会尝试为我的编译器调整它。
    • @user 将其移到标题中,#include "get_function.hpp" 是一行。 :) 有什么错误?
    • 我使用了“#define nullptr NULL;”作为一种解决方法并进入 decltype(detail::get_function((Tuple*)nullptr)) get_function() q.cc:19: error: expected ')' before ';' token q.cc:19: error : ')' 标记之前的预期 unqualified-id
    • @user:为什么需要定义nullptr?它应该已经定义了。请记住,我的代码未经测试,我只是从大脑中编写的;错误可能是我的,而不是你的。
    【解决方案2】:

    经过一番试验,我发现可以使用 lambda 表达式:

    #include <tuple>
    #include <string>
    
    typedef std::tuple<int, std::string> Tuple;
    auto t = [] (Tuple& t) { return std::get<1> (t); };
    

    如果你需要经常使用它,你总是可以写一个宏:

    #define REFERENCE_GET(N, Tuple) \
        [] (Tuple &t) { return std::get<N> (t); }
    

    【讨论】:

    • 我还没有认为自己“准备好”使用 lambda,但在 C++0x 中似乎没有办法绕过它们。唯一的缺点似乎是由于缺少 result_type,lambda 不能用作 boost::transform_iterator 的输入,但这是另一回事。谢谢。
    【解决方案3】:

    下面的代码对我有用。诀窍是使用函数指针 typedef 而不是函数引用 typedef。 令我印象深刻的是,编译器不需要所有模板参数,但可以通过重载函数类型选择性地解决缺失的参数。

    #include <tuple>
    #include <string>
    
    typedef std::tuple<int,std::string> Tuple;
    typedef std::string& (*PFun)(Tuple&);
    
    PFun p1=(PFun)std::get<1U>;
    PFun p2=(PFun)std::get<1U,int,std::string>;
    

    一行:

    auto p3=(std::string& (*)(Tuple&))std::get<1U>;
    

    很抱歉回答我自己的问题。晚上睡觉会有很大的不同。

    【讨论】:

    • 啊,如果您可以重新指定元组类型,它确实要短得多。 :) 我的大部分代码都在为您提取它们。
    • 确实,我没有明确说明不需要元组类型。但是,该标准为此提供了 tuple_element 。所以在上面的代码中用 std::tuple_element 替换 std::string 也可以处理这个问题。
    猜你喜欢
    • 1970-01-01
    • 2020-11-07
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 2014-10-26
    • 2018-06-02
    • 2020-07-07
    • 2014-05-04
    相关资源
    最近更新 更多