C++ 是否有一种方法可以编写一个宏,只使用变量名(即FWD(t),它相当于std::forward<;t>;(t))来完成完美的转发?
我有这样的想法(比如说): 然而,这:C++ 是否有一种方法可以编写一个宏,只使用变量名(即FWD(t),它相当于std::forward<;t>;(t))来完成完美的转发?,c++,templates,c++11,decltype,perfect-forwarding,C++,Templates,C++11,Decltype,Perfect Forwarding,我有这样的想法(比如说): 然而,这: void foo(int&a){cout#定义FWD(a)std::forward(a) 将起作用。只要a是变量的名称,decltype(a)就是它声明的类型,这就是您应该传递给forward作为其类型参数的类型 如果你传递一个表达式,事情可能会变得奇怪。然而,我想不出一个表达式失败的例子 当然,这不适用于该方法的一些更高级的使用 #define FWD(a) std::forward<decltype(a)>(a) 定义前向(a)标准::
void foo(int&a){cout#定义FWD(a)std::forward(a)
将起作用。只要a
是变量的名称,decltype(a)
就是它声明的类型,这就是您应该传递给forward
作为其类型参数的类型
如果你传递一个表达式,事情可能会变得奇怪。然而,我想不出一个表达式失败的例子
当然,这不适用于该方法的一些更高级的使用
#define FWD(a) std::forward<decltype(a)>(a)
定义前向(a)标准::前向(a)
事实上,正如我们所看到的
void foo(int&a){cout“我猜它不会在所有情况下都起作用”你为什么这么说?@0x499602D2:如果参数是t&&t
,那么decltype(t)
不会给你t&
,而你应该把t
传递给std::forward?@Claudiu,结果是一样的std::forward(t)
equalstd::forward(t)
,不是吗?它不在标准中,因为他们不喜欢宏all@WorldSEnder:它最终会产生误导,例如,FWD(v)
会起作用,但FWD((v))
不会起作用(因为decltype(v)!=decltype((v))
),如果参数是t&&t
,则不会decltype(t)
给你T&
,而你应该把T
传给std::forward?还有forward
更高级的用法是什么,在哪里不起作用?@Claudiu PassingT&
与std::forward
一起工作,就像T
。std::forward
更高级的用法与e当前变量对如何转发的声明,例如一次调用lambda,它转发它通过引用捕获的内容。
template <typename Collection, typename Item>
void foo_collection(Collection&& c, Item&& i) {
foo(FWD(c), FWD(i));
}
#define FWD(v) \
std::forward< \
typename std::remove_const<\
typename std::remove_reference<\
decltype(v)>::type>::type>(v)
void foo(int& a) { cout << "ref" << endl; }
void foo(const int& a) { cout << "cref" << endl; }
template <typename T>
void call_foo(T&& t) { foo(FWD(t)); }
int main() {
int a = 10;
foo(10); // 1) prints cref
foo(a); // 2) prints ref
call_foo(10); // 3) prints cref
call_foo(a); // 4) prints cref
return 0;
}
#define FWD(a) std::forward<decltype(a)>(a)
#define FWD(a) std::forward<decltype(a)>(a)
void foo(int& a) { cout << "lref" << endl; }
void foo(const int& a) { cout << "cref" << endl; }
void foo(int&& a) { cout << "rref" << endl; }
template <typename T>
void call_foo(T&& t) { foo(FWD(t)); }
int main() {
int a = 10;
call_foo(10); // 3) prints rref
call_foo(a); // 4) prints lref
return 0;
}