C++ 完美转发容器元素

C++ 完美转发容器元素,c++,c++11,perfect-forwarding,C++,C++11,Perfect Forwarding,类似于,但不是对象的完美转发成员,我想知道如何完善STL容器的转发元素,即类似于 struct X {}; void f(X&); void f(X&&); template <typename Vector> void g(Vector&& v, size_t i) { if (is_lvalue_reference<Vector>::value) { f(v[i]); } else { f(move(v

类似于,但不是对象的完美转发成员,我想知道如何完善STL容器的转发元素,即类似于

struct X {};
void f(X&);
void f(X&&);

template <typename Vector>
void g(Vector&& v, size_t i) {
  if (is_lvalue_reference<Vector>::value) {
    f(v[i]);
  } else {
    f(move(v[i]));
  }
}
struct X{};
无效f(X&);
无效f(X&&);
模板
空g(向量和v,大小i){
if(is_lvalue_reference::value){
f(v[i]);
}否则{
f(移动(v[i]);
}
}

你能举一个例子说明你想做什么吗?@Barry,我已经按照规则把它精简到最低限度了。实际用例是复杂的。我想从
向量
向量
,…..创建
向量
,其中每个元素
T
都是由
U1
U2
。。。。
vector
的每个数组可以是&或&&,我希望
Ui
可以完美地转发。类似于?@Barry的目标是从
v[I]
移动到iff
v
绑定到一个右值。因此,如果我们有一个左值引用的右值元组引用,应该
forward\like(get\tuple\u member(t))
返回右值还是左值?我想我们无法从访问器函数中区分“成员”和“引用成员”。也许我们应该做
std::forward(v)[i]
vector::operator[]
应该有一个右值重载?嗯。理论上,
std::forward(foo).field
是我们在这里要模拟的,不是吗?@Yakk是的,所以转发右值元组的左值引用成员应该会产生左值。(我相信
std::get
已经处理了吗?)点头,但上面的方法不行:唯一的方法是“进入”类,并知道您是否拥有
T
T&
,因为任何明智的访问者在这两种情况下都会返回
T&
。我只是注意到,如果你有一个(不存在的)
向量
,如果容器是一个右值,上面的
将移动
,并思考是否有办法绕过它。我没看到。从根本上说,使
forward_-like
弱于支持右值的访问器。而且支持右值的访问器看起来总是脏兮兮的(你需要知道你不是真的在移动,只是移动了那一个字段)。@Yakk确实,我们需要知道存储的东西是否实际上是一个引用,这意味着某种直接查询容器的方法(
tuple\u element\u t
带元组;对于容器可能是
value\u type
).
namespace detail {
    template<class T, class U>
    using forwarded_type = std::conditional_t<std::is_lvalue_reference<T>::value,
                                              std::remove_reference_t<U>&, 
                                              std::remove_reference_t<U>&&>;
}
template<class T, class U>
detail::forwarded_type<T,U> forward_like(U&& u) {
    return std::forward<detail::forwarded_type<T,U>>(std::forward<U>(u));
}

template <typename Vector>
void g(Vector&& v, size_t i) {
  f(forward_like<Vector>(v[i]));
}
template<class T, class...Vectors>
std::vector<T> make_vector(Vectors&&...vectors){
    auto n = std::min({vectors.size()...});
    std::vector<T> ret; 
    ret.reserve(n);
    for(decltype(n) i = 0; i < n; ++i)
        ret.emplace_back(forward_like<Vectors>(vectors[i])...);
    return ret;
}