我已经重新安排了一个关于std :: forward with template的例子。
我使用了包装函数,如果我将其声明为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);
}
但是如果我想从包装函数返回一个类型,无论我使用什么,我都会在lvalues函数调用上出错,基金(x,y),说明&#34; ....函数没有匹配参数&#34; ...另一个基金(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));
}
它也不起作用,说明&#34;拒绝(类型)是C ++ o1扩展......&#34;那,谢谢编译器,但它确实有帮助。
一个无意义的可怕解决方案是将返回类型或T或U声明为返回类型。即使我收到警告,也会编译&#34;引用与本地变量关联的堆栈内存&#34;
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的解决方案应该可行,但事实并非如此。
对此有何建议?
感谢您的帮助
答案 0 :(得分:5)
decltype
表示其参数中给出的表达式的类型。所以
decltype(T {}, U {})
将是表达式T{}, U{}
的类型。这里有逗号运算符,因此表达式的类型是逗号后面的表达式类型U{}
,因此decltype (T{}, U{})
为您提供类型U
(更准确地说,我猜是U &&
,因为它是一个右值。)
你想要的是
decltype(T{} + U{})
或
decltype(a+b)
(感谢Jonathan Wakely,见评论)。