gpt4 book ai didi

c++ - 为什么一个完美的转发功能必须模板化?

转载 作者:IT老高 更新时间:2023-10-28 22:04:40 28 4
gpt4 key购买 nike

为什么下面的代码有效:

template<typename T1>
void foo(T1 &&arg) { bar(std::forward<T1>(arg)); }

std::string str = "Hello World";
foo(str); // Valid even though str is an lvalue
foo(std::string("Hello World")); // Valid because literal is rvalue

但不是:

void foo(std::string &&arg) { bar(std::forward<std::string>(arg)); }

std::string str = "Hello World";
foo(str); // Invalid, str is not convertible to an rvalue
foo(std::string("Hello World")); // Valid

为什么示例 2 中的左值没有以与示例 1 中相同的方式解析?

另外,为什么标准认为需要在 std::forward 中提供参数类型而不是简单地推导它很重要?简单地向前调用就是表明意图,不管是什么类型。

如果这不是标准的东西,只是我的编译器,我使用的是 msvc10,这可以解释糟糕的 C++11 支持。

谢谢

编辑 1:将文字“Hello World”更改为 std::string("Hello World") 以生成右值。

最佳答案

首先,read this全面了解转发。 (是的,我将大部分答案委托(delegate)给其他地方。)

总而言之,转发意味着左值保持左值,右值保持右值。你不能用一种类型来做到这一点,所以你需要两个。因此,对于每个转发的参数,您需要该参数的两个版本,这需要该函数总共有 2N 个组合。您可以对函数的所有组合进行编码,但如果您使用模板,则会根据需要为您生成各种组合。


如果您尝试优化拷贝和移动,例如:

struct foo
{
foo(const T& pX, const U& pY, const V& pZ) :
x(pX),
y(pY),
z(pZ)
{}

foo(T&& pX, const U& pY, const V& pZ) :
x(std::move(pX)),
y(pY),
z(pZ)
{}

// etc.? :(

T x;
U y;
V z;
};

那么你应该停下来这样做:

struct foo
{
// these are either copy-constructed or move-constructed,
// but after that they're all yours to move to wherever
// (that is, either: copy->move, or move->move)
foo(T pX, U pY, V pZ) :
x(std::move(pX)),
y(std::move(pY)),
z(std::move(pZ))
{}

T x;
U y;
V z;
};

你只需要一个构造函数。 指南:如果您需要自己的数据拷贝,请在参数列表中制作该拷贝;这使得决定是复制还是向上移动到调用者和编译器。

关于c++ - 为什么一个完美的转发功能必须模板化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8349595/

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