返回类型的包装函数C++ 11

Max*_*cci 3 c++11

我已经重新安排了一个关于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);

 }
Run Code Online (Sandbox Code Playgroud)

但是如果我想从包装器函数返回一个类型,无论我使用什么,我都会在lvalues函数调用ONLY,基金(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));

 }
Run Code Online (Sandbox Code Playgroud)

甚至使用c ++ 14 decltype(auto)来推断转发函数和类似包装器的返回类型

 template<typename T,typename U> decltype(auto) func(T&& a, U && b) {
 return summation(forward<T>(a), forward<U>(b));

 }
Run Code Online (Sandbox Code Playgroud)

它也不起作用,说"拒绝(类型)是C++ o1扩展......",谢谢编译器,但它确实有帮助.

一个无意义的可怕解决方案是将返回类型或T或U声明为返回类型.即使我收到警告声明"引用与本地变量关联的堆栈内存返回",这也会编译

 template<typename T,typename U> U func(T&& a, U && b)   {
 auto res =  summation(forward<T>(a), forward<U>(b));
 return res;

 } 
Run Code Online (Sandbox Code Playgroud)

std :: forward的返回类型给出(t)要转发的对象是

 static_cast<T&&>(t) 
Run Code Online (Sandbox Code Playgroud)

因此,第一个使用auto的解决方案应该可行,但事实并非如此.

有什么建议吗?

谢谢你的帮助

Joh*_*hnB 5

decltype表示其参数中给出的表达式的类型.所以

decltype(T {}, U {})
Run Code Online (Sandbox Code Playgroud)

将是表达式的类型T{}, U{}.这里有逗号运算符,因此表达式的类型是逗号后面的表达式的类型U{},因此decltype (T{}, U{})给出了类型U(更确切地说U &&,我猜,因为它是一个右值).

你想要的是什么

decltype(T{} + U{})
Run Code Online (Sandbox Code Playgroud)

要么

decltype(a+b)
Run Code Online (Sandbox Code Playgroud)

(感谢Jonathan Wakely,见评论).

  • `decltype(a + b)`会更好,迟到指定的返回类型的点是它们可以引用函数参数. (5认同)