C++ 完美转发对象的成员
假设我有两个C++ 完美转发对象的成员,c++,c++11,rvalue-reference,perfect-forwarding,C++,C++11,Rvalue Reference,Perfect Forwarding,假设我有两个structs: struct X {}; struct Y { X x; } 我有以下职能: void f(X&); void f(X&&); 我如何编写一个函数g(),分别将Y&或Y&完美地转发到X&或X&到f(): template <typename T> void g(T&& t) { if (is_lvalue_reference<T>::value) { f(t.x); } else {
struct
s:
struct X {};
struct Y { X x; }
我有以下职能:
void f(X&);
void f(X&&);
我如何编写一个函数g()
,分别将Y&
或Y&
完美地转发到X&
或X&
到f()
:
template <typename T>
void g(T&& t) {
if (is_lvalue_reference<T>::value) {
f(t.x);
} else {
f(move(t.x));
}
}
模板
无效g(T&T){
if(is_lvalue_reference::value){
f(t.x);
}否则{
f(move(t.x));
}
}
上面的代码说明了我的意图,但随着参数数量的增加,它的可伸缩性不是很强。有没有一种方法可以让它实现完美的转发并使其具有可扩展性?我认为这会奏效,尽管我不确定:
template<class T, class M>
struct mforward {
using type = M&&;
};
template<class T, class M>
struct mforward<T&, M> {
using type = M&;
};
template <typename T>
void g(T&& t) {
f(std::forward<typename mforward<T, decltype(t.x)>::type>(t.x));
}
模板
结构向前{
使用type=M&;
};
模板
结构向前{
使用type=M&;
};
模板
无效g(T&T){
f(标准:正向(t.x));
}
模板
无效g(T&T){
f(std::forward(t.x);
}
我认为将is_lvalue_reference::value
更改为is_lvalue_reference::value
将具有您想要的语义,但我认为您想要的语义是有问题的…(对于拙劣的答案,我感到抱歉)。我认为它无法扩展的原因是因为设计一开始就有问题。“移动”子对象意味着什么?这将在什么状态下离开主对象?即使有一个简单的方法来编写,它看起来像是结构糟糕的代码…+1我必须用libc++解决几乎完全相同的问题。我提出的解决方案看起来与Pubby的非常相似。我不仅想将T
的l/r值“应用”到M
,还想将T
的cv资格应用到M
。我找到了数据成员以外的应用程序。出于好奇,我把它称为\uu apply\u cv
,它是开源代码:@Howard请参阅我的答案以获取替代方案。还是我错过了什么?还有@Howard谈论简历资格让我想到了这个答案的一个缺陷decltype(t.x)
仅提供声明的x
类型。如果T
是const
,但是x
被声明为inta
,那么您的转发将尝试将内容转发为int&
/int&
。您需要说一些类似于typename remove\u reference::type
的话来考虑t
的常量。这也考虑了mutable
成员,但我不知道move在哲学上对一个const
对象的可变成员意味着什么。@Johannes:我同意,你的解决方案更适合这个用例。@Howard:如果Johannes的解决方案不起作用,情况会是什么样子,但是\u apply\u cv
一个人会@Pubby,因为rvalue.foo
是一个rvalue。我能想到为什么它可能是有意义的(如果容器的生命周期很短并且是一个右值,那么所包含的对象也共享该属性),但我不熟悉其原理,也不知道其原理,所以我不能对此说任何话。rvalue.foo
应该是一个xvalue属性。@curi一些委员会成员这样说。但是,他会怎么解释“rvalue”(对象表达式)有时保持为prvalue的原因呢?反对将成员选择设置为xvalue是因为它的动态类型不能与表达式的静态类型不同。这正是我要寻找的答案。真是个天才!!
template <typename T>
void g(T&& t) {
f(std::forward<T>(t).x);
}