【发布时间】:2014-08-01 09:06:12
【问题描述】:
我已经重新安排了一个关于带有模板的 std::forward 的示例。
我使用了一个包装函数,一切都很好,如果我将它声明为 void 函数。它按预期工作。
#include<iostream>
using namespace std;
template <typename T, typename U>
auto summation(T const &a, U const& b) -> decltype(T{}, U{}) {
cout << "call by lvalue" << endl;
return a+b;
}
template <typename T, typename U>
auto summation(T&& a, U && b) -> decltype(T{},U{}) {
cout << "call by rvalue" << endl;
return a+b;
}
template<typename T,typename U> void func(T&& a, U && b) {
summation(forward<T>(a), forward<U>(b));
}
int main() {
int x = 10;
double y = 20;
func(x,y);
func(10,20);
}
但是如果我想从包装函数返回一个类型,无论我使用什么,我都会在左值函数调用时遇到错误,仅基金(x,y),说明“......函数与参数不匹配“......另一个基金(10,20)有效。
template<typename T,typename U> auto func(T&& a, U && b) -> decltype(T{}, U{}) {
return summation(forward<T>(a), forward<U>(b));
}
甚至使用 c++14 decltype(auto) 来推断转发函数和类似包装器的返回类型
template<typename T,typename U> decltype(auto) func(T&& a, U && b) {
return summation(forward<T>(a), forward<U>(b));
}
它也不起作用,说明“decline(type) is C++o1 extension...”,谢谢编译器,但它确实有帮助。
一个无意义的可怕解决方案是将返回类型或 T 或 U 声明为返回类型。即使我收到一条警告说“引用与返回的局部变量关联的堆栈内存”,这也会编译
template<typename T,typename U> U func(T&& a, U && b) {
auto res = summation(forward<T>(a), forward<U>(b));
return res;
}
std::forward的返回类型给定(t)要转发的对象是
static_cast<T&&>(t)
因此,第一个使用 auto 的解决方案应该可以工作,但它不能。
对此有什么建议吗?
感谢您的帮助
【问题讨论】:
-
你确定
decltype(T{}, U{})是一个有用的结构吗? -
"decline(type) 是 C++o1 扩展..." ?!拒绝?
-
您的第二个
summation重载不仅用于右值,它也将被调用用于非常量左值。你不需要两个重载,阅读isocpp.org/blog/2012/11/… -
为什么不直接使用
template<typename T,typename U> auto func(T&& a, U && b) -> decltype (summation (forward<T>(a), forward<U>(b))) { return summation(forward<T>(a), forward<U>(b)); }?它应该正确处理所有情况。 -
是的,JohnB 这工作正常,并且它工作 decltype(a+b) 乔纳森建议但只有当我使用 auto res = summation((forward
(a), forward( b)). 如果我使用 return summation(forward (a), forward(b)) 编译失败,说明“没有对 double 类型的 const lvalue 引用不能绑定 decltype(int() 类型的临时+ 双());
标签: c++11