auto return 类型不推导引用
auto return type not deducing reference
我有以下代码:
#include <iostream>
struct C {
int a;
int& get() { return a; }
};
struct D {
int a;
int get() { return a; }
};
template <typename T>
auto foo(T o) { // no sample code is complete without a foo
return o.get();
}
int main()
{
C c;
D d;
c.a = 2;
d.a = 42; // no sample code is complete without a 42
std::cout << "c=" << c.a << ", d=" << d.a << "\n";
c.get() = 3;
//d.get() = 43;
std::cout << "c=" << c.a << ", d=" << d.a << "\n";
foo(c) = 4; // <--- why won't this work?
//foo(d) = 44;
std::cout << "c=" << c.a << ", d=" << d.a << "\n";
}
为什么标记为编译的行不编译?似乎编译器将 foo<C>
的 return 类型推断为 int
而不是我期望的 int&
。为什么会这样,我怎样才能得到它来推断引用呢?
给定 auto
,它被声明为 non-reference,所以我们正在处理 pass-by-value 的情况。并且 auto
follows the rules of template argument deduction; int&
的引用部分将被忽略,则推导类型为 int
.
您可以改用 decltype(auto)
(C++14 起)。
type is decltype(e)
, where e
is the initializer.
template <typename T>
decltype(auto) foo(T&& o) { // no sample code is complete without a foo
return o.get();
}
return类型推导为decltype(o.get())
,根据decltype
,
的规则
if the value category of expression is lvalue, then decltype yields T&
;
c.get()
returns int&
,这是一个左值,然后我们得到 return 类型 int&
而不是 int
。
顺便说一句:请注意,如果 o
仍然通过 by-value,returned 引用将被悬挂。
我有以下代码:
#include <iostream>
struct C {
int a;
int& get() { return a; }
};
struct D {
int a;
int get() { return a; }
};
template <typename T>
auto foo(T o) { // no sample code is complete without a foo
return o.get();
}
int main()
{
C c;
D d;
c.a = 2;
d.a = 42; // no sample code is complete without a 42
std::cout << "c=" << c.a << ", d=" << d.a << "\n";
c.get() = 3;
//d.get() = 43;
std::cout << "c=" << c.a << ", d=" << d.a << "\n";
foo(c) = 4; // <--- why won't this work?
//foo(d) = 44;
std::cout << "c=" << c.a << ", d=" << d.a << "\n";
}
为什么标记为编译的行不编译?似乎编译器将 foo<C>
的 return 类型推断为 int
而不是我期望的 int&
。为什么会这样,我怎样才能得到它来推断引用呢?
给定 auto
,它被声明为 non-reference,所以我们正在处理 pass-by-value 的情况。并且 auto
follows the rules of template argument deduction; int&
的引用部分将被忽略,则推导类型为 int
.
您可以改用 decltype(auto)
(C++14 起)。
type is
decltype(e)
, wheree
is the initializer.
template <typename T>
decltype(auto) foo(T&& o) { // no sample code is complete without a foo
return o.get();
}
return类型推导为decltype(o.get())
,根据decltype
,
if the value category of expression is lvalue, then decltype yields
T&
;
c.get()
returns int&
,这是一个左值,然后我们得到 return 类型 int&
而不是 int
。
顺便说一句:请注意,如果 o
仍然通过 by-value,returned 引用将被悬挂。