我想知道是否可能让绑定表达式不返回对象,而是 对象的成员。这是一个想法(我希望直接从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实现,但这不是问题。)
谢谢!
答案 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相比的简洁优势就越消失。哦,好吧。