gpt4 book ai didi

c++ - 完善的转发和模板

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:28:50 27 4
gpt4 key购买 nike

当我有一个看起来像这样的代码时:

template<class T>
void f_(const T& arg)
{
cout << "void f(const T& arg): Cannot modify\n";
}

template<class T>
void f_(T&& arg)
{
cout << "void f(T&& arg): Can modify\n";
}

主要我称之为:

int main()
{

MemoryBlock block;
f_(block);
f_(MemoryBlock());
return 0;
}

输出是:
"void f(T&& arg): 可以修改\n";
"void f(T&& arg): 可以修改\n";

但是当我将此代码更改为非泛型代码时,我将拥有常规函数,而不是函数模板,

void f(const MemoryBlock&)
{
cout << "In f(const MemoryBlock&). This version cannot modify the parameter.\n";
}

void f(MemoryBlock&&)
{
cout << "In f(MemoryBlock&&). This version can modify the parameter.\n";
}

输出更“直观”:
“在f(const MemoryBlock&)中。此版本无法修改参数。”;
"在f(MemoryBlock&&)中。这个版本可以修改参数。";

在我看来,只有将函数从模板更改为非模板,才能完全改变右值引用的推导规则。
如果有人能向我解释一下,我将非常感激。

最佳答案

当您使用 T&& 时,那不是右值引用,而是通用引用参数。它们的声明方式相同,但行为不同。

当您删除模板参数时,您不再处于可推导的上下文中,它实际上是一个右值引用:当​​然,它们只绑定(bind)到右值。

在可推导的上下文中(即发生类型推导时),T&&可以是右值引用左值引用。通用引用几乎可以绑定(bind)到所有组合( constconst volatile 等),在您的情况下: const T& .

现在您的思路是高效重载右值,然后重载左值,但实际情况是通用引用重载在推导模板参数时更匹配。因此,它将在 const T& 上被选中。过载。

通常,您只想保留通用引用功能并将其与 std::forward<T>() 配对完善论点。这消除了对 const T& 的需要过载,因为通用引用版本将接管。

请注意,仅仅因为您看到了 &&在可推导的上下文中,这并不意味着它是一个普遍的引用; &&需要附加到被推导的类型,所以这里有一个实际上是右值引用的例子:

template<class T>
void f_(std::vector<T>&& arg) // this is an rvalue reference; not universal
{
cout << "void f(T&& arg): Can modify\n";
}

这里有一个关于这个问题的精彩演讲:https://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Scott-Meyers-Universal-References-in-Cpp11

关于c++ - 完善的转发和模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33172392/

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