簡體   English   中英

為什么不總是使用std :: forward?

[英]Why not always use std::forward?

std::movestd::forward之間的區別是眾所周知的,我們使用后者保留轉發對象的值類別,並使用前者轉換為rvalue引用以啟用移動語義。

有效的現代C ++中 ,存在一種指導原則

在rvalue引用上使用std::move ,在通用引用上使用std::move std::forward

但在以下場景中( 以及我們不想更改值類別的場景 ),

template <class T>
void f(vector<T>&& a)
{
    some_func(std::move(a)); 
}

如果a不是轉發引用而是簡單的右值引用,那么執行以下操作是否完全相同?

template <class T>
void f(vector<T>&& a)
{
    some_func(std::forward<decltype(a)>(a)); 
}

因為這可以很容易地封裝在像這樣的宏中,

#define FWD(arg) std::forward<decltype(arg)>(arg)

如此總是使用這個宏定義不方便嗎?

void f(vector<T>&& a)
{
    some_func(FWD(a)); 
}

寫這兩種方式不完全相同嗎?

呃。 值得商榷。 在您的特定示例中,它是等效的。 但我不會養成習慣。 一個原因是因為您希望在轉發和移動之間進行語義區分。 另一個原因是因為要擁有一致的API,除了FWD之外你還必須擁有MOV ,這看起來很糟糕而且什么都不做。 但更重要的是,您的代碼可能會意外失敗。

請考慮以下代碼:

#include <iostream>

using namespace std;

#define FWD(arg) std::forward<decltype(arg)>(arg)

struct S {
    S() { cout << "S()\n"; }
    S(const S&) { cout << "S(const S&)\n"; }
    S(S&&) { cout << "S(S&&)\n"; }
};

void some_func(S) {}

void f(S&& s)
{
    some_func(FWD(s)); 
}

int main()
{
    f(S{});
}

打印出來

S()
器S(s &&)

但是,如果我只是改變FWD線以獲得另一對(看似可選的)括號,如下所示:

void f(S&& s)
{
    some_func(FWD((s))); 
}

現在我們得到了

S()
S(const S&)

這是因為現在我們在表達式上使用了decltype ,它計算為左值引用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM