簡體   English   中英

為此缺少 std::forward 之類的東西

[英]Missing something like std::forward for this

我相信我理解C++中完美轉發的概念。 但我錯過了“這個”類似的東西。 讓我們:

class X {
  std::vector<int> vec;
public:
  std::vector<int> const &getVec() const & { return vec; }
  std::vector<int> &      getVec() &       { return vec; }
  std::vector<int>        getVec() &&      { return std::move(vec); }
};

由於std::forward()壓縮了類似的參數定義,我想為“this”提供類似的東西。 就像是:

class X {
  std::vector<int> vec;
public:
  auto &&getVec() /*???const &*/ { return thisForward(vec); }
};

是否可能出現上述情況(或在 STL 或 boost 中可用)? 或者,至少,有一些解決方法嗎?

加上一個額外的問題(僅用於驗證),我上面的 3 個getVec()重載有意義嗎? 有這樣的3個重載可以(出於優化原因)嗎? (假設“X”是一個類似容器的 class。)

對於 C++20,你可以接近,但我不明白如何完全按照你的要求去做。

如果您get變成靜態/朋友 function 它可以工作。 我無法將輔助類型的重復次數降至零,但也許可以對此進行改進。 如果您願意支付引用成員的費用,這可能會通過包裝器來實現,但該包裝器必須存儲對該成員的引用。

#pragma once
#include <type_traits>

template <typename T>
concept lvalue = std::is_lvalue_reference_v<T> && !std::is_const_v<std::remove_reference_t<T>>;
template <typename T>
concept lcvalue = std::is_lvalue_reference_v<T> && std::is_const_v<std::remove_reference_t<T>>;

template <typename T, typename R>
struct RT {
  using type = R;
};
template <lvalue T, typename R>
struct RT<T,R> {
  using type = std::add_lvalue_reference_t<std::remove_const_t<R>>;
};
template <lcvalue T, typename R>
struct RT<T,R> {
  using type = std::add_lvalue_reference_t<std::add_const_t<R>>;
};

template <typename T, typename R>
using RT_t = typename RT<T,R>::type;

例子:

#include <vector>
#include <cassert>
#include "rt.h"

namespace {
  struct X {
    std::vector<int> v;

    template <typename Self>
    friend RT_t<Self,std::vector<int>> get(Self&& self) {
      return std::forward<RT_t<Self,std::vector<int>>>(self.v);
    }
  };
}

int main() {
  X x{std::vector{1,2,3}};
  assert(x.v.size() == 3);
  X& xr = x;
  get(xr).push_back(1);
  assert(x.v.size() == 4);
  //X const& xc = x;
  //get(xc).push_back(1); // does not compile
  {
    std::vector<int> vec = get(std::move(x));
    assert(vec.size() == 4);
  }
  assert(x.v.size() == 0);
}

所以,缺點:

  • 必須寫get(x)而不是x.get()
  • 定義get one 時必須重復RT_t<Self,std::vector<int>>

編譯器資源管理器上的演示

從 C++23 開始,可以顯式聲明 this 參數 然后,您將能夠做您要求的事情:

class X {
    std::vector<int> vec;
public:
    template<class Self>
    decltype(auto) getVec(this Self&& self) {
        return std::forward<Self>(self).vec;
    }
};

你可以在這里閱讀更多。

暫無
暫無

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

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