考虑以下代码。
struct Widget {
int& get();
};
template<typename X>
auto func_1(X& x) {
return x.get();
}
template<typename X>
auto func_2(X& x) -> decltype(x.get()) {
return x.get();
}
当使用类型为
Widget
的左值调用时,函数 func_1
将使用返回类型 int
进行实例化,其中函数 func_2
将具有返回类型 int&
。
此外,
func_1
和func_2
之间的区别在于,对func_2
执行“表达式SFINAE”。因此,对于没有 X
成员的类型 .get()
,func_2
将不会参与重载决策。
我的问题是:我们如何在执行表达式 SFINAE 的同时获得
func_1
的返回类型行为?
以下
func_3
似乎适用于我测试的情况,但我觉得应该有一个更简单的替代方案。另外,我不确定 func_3
是否在所有情况下都与 func_1
具有完全相同的返回类型。
template<typename X>
auto func_3(X& x) -> std::remove_cvref_t<std::decay_t<decltype(x.get())>> {
return x.get();
}
定义
func_1
时可以使用func_2
,如下所示:
template<typename X>
auto func_1(X& x) {
return x.get();
}
template<typename X>
auto func_2(X& x) -> decltype(func_1(x)) {
return x.get();
}
int main()
{
Widget w;
// func_1(w); //return type is int
func_2(w);//return type is int as well
}