gpt4 book ai didi

c++ - 转发引用 : returning T when given T&& and T& when given T&

转载 作者:行者123 更新时间:2023-11-27 23:47:55 27 4
gpt4 key购买 nike

考虑一个类A,我如何编写一个具有与

相同行为的模板
A& pretty(A& x)
{
/* make x pretty */
return x;
}

A pretty(A&& x)
{
/* make x pretty */
return x;
}

知道我想:

  1. 以完全相同的方式修改参数 (x),与参数是右值引用还是左值引用无关(实际上,这两个部分 /* make x pretty */ 相同),因此具有单一功能;

  2. 避免不必要的复制;

  3. 能够使用函数修改变量;

  4. 能够“流水线化”函数调用,无论参数是右值还是左值。

作为 3. 和 4. 的示例,请考虑以下用例:

void read_A(const A& x) { /* ... */ }
void take_A(A&& x) { /* ... */ }

A x();
read_A(pretty(x));
take_A(pretty(A()));

我的想法是利用转发引用,同时将允许的参数限制为对 A 的引用。但是返回类型呢?

template<typename T>
std::enable_if_t<std::is_same<T, A>::value>
/*???*/ pretty(T&& x)
{
/* make x pretty */
return x; //?
}

最佳答案

为什么不直接写

#include <iostream>

template <class T>
T somefunc(T&& a) {
/* do something with a */
std::cout << __PRETTY_FUNCTION__ << '\n';
return std::forward<T>(a);
}

int main(int argc, char* argv[]) {
int a = 5;

somefunc(a);
somefunc(5);

return 0;
}

会返回

T somefunc(T &&) [T = int &]
T somefunc(T &&) [T = int]

如您所见,函数具有您想要的签名。在第一次调用中,T 获得了 int &,因此,int & 的返回值。在第二个中,您有 T = int = int &&,这也是您想要的。

编辑。 顺便说一下,您最初的想法是应用 std::is_same 来禁用 A 以外类型的重载解析似乎也错了根据cppreference ,

If T and U name the same type with the same const-volatile qualifications, provides the member constant value equal to true. Otherwise value is false.

因此,您可能想要使用类似decay 的东西,或者至少是remove_cvremove_reference 的组合来应用您想要的逻辑.下面是上述代码的修改版本,现在包含重载解析启动器。

#include <iostream>
#include <type_traits>

template <class T> T somefunc(T &&a) {
/* do something with a */
std::cout << __PRETTY_FUNCTION__ << '\n';
return std::forward<T>(a);
}

template <class T, typename std::enable_if<
std::is_same<typename std::decay<T>::type, float>::value,
int>::type = 0>
T onlyfloat_correct(T &&a) {
/* do something with a */
std::cout << __PRETTY_FUNCTION__ << '\n';
return std::forward<T>(a);
}

template <class T,
typename std::enable_if<std::is_same<T, float>::value, int>::type = 0>
T onlyfloat_wrong(T &&a) {
/* do something with a */
std::cout << __PRETTY_FUNCTION__ << '\n';
return std::forward<T>(a);
}

int main(int argc, char *argv[]) {
int a = 5;
const float b = 5;

somefunc(a);
somefunc(5);

onlyfloat_correct(b);
// onlyfloat_wrong(b);

return 0;
}

关于c++ - 转发引用 : returning T when given T&& and T& when given T&,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49087373/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com