通过std :: bind从对象成员中检索值

时间:2018-03-21 13:55:31

标签: c++ bind

我想知道是否可能让绑定表达式不返回对象,而是 对象的成员。这是一个想法(我希望直接从val获得B):

struct A
{
    A(float _val) : val(_val) {}
    float val;
};

struct B
{
    B(float _val) : a(_val) {}
    A a;
};

int main()
{
    B b{ 2.0f };
    auto get_a_from_b = std::bind(&B::a, std::placeholders::_1);
    const A& a = get_a_from_b(b); // ok

    auto get_val_from_a = std::bind(&A::val, std::placeholders::_1);
    float val = get_val_from_a(a); // ok, val = 2.0f

    // error
    auto get_val_from_b = std::bind(&B::a::val, std::placeholders::_1);
    auto x = get_val_from_b(b);
}

特别是,B::a::val的概念可以起作用还是在概念上是错误的? (我知道这可以通过lambda实现,但这不是问题。)

谢谢!

1 个答案:

答案 0 :(得分:0)

好的liliscent说,它不能直接完成。但是,您可以将它们链接在一起:

int val = std::mem_fn(&A::val)(std::mem_fn(&B::a)(b));

mem_fn是这项努力的更好功能。)

这可以通过其自身的功能变得更加紧凑:

#include <functional>
#include <array>
#include <vector>
#include <iostream>

struct A
{
    A(int _val = 0) : val(_val) {}
    int val;
};
struct B
{
    B(int _val = 0) : a(_val) {}
    A a;
};

template<typename Elem, typename Head, typename... Tail>
constexpr decltype(auto) getElement(const Elem& _elem, Head&& _head, Tail&&... _tail)
{
    auto fn = std::mem_fn(std::forward<Head>(_head));
    if constexpr(sizeof...(_tail) == 0)
    {
        return fn(_elem);
    }
    else
    {
        return getElement(fn(_elem), std::forward<Tail>(_tail)...);
    }
}

int main()
{
    B b{ 7 };
    int i = getElement(b, &B::a, &A::i); // get the a from B first, then get the val from that a
    int j = getElement(b.a, &A::i);

    return 0;
}

但是如果向上堆叠越多,与lambda相比的简洁优势就越消失。哦,好吧。