簡體   English   中英

如何為 std::pair 引用包裝器的范圍定義 C++ 概念?

[英]How to define a C++ concept for a range to a std::pair of reference wrappers?

請參閱下面的代碼(也在此處https://www.godbolt.org/z/hvnvEv1ar )。 如果我取消注釋rngpair的約束,代碼將無法編譯。 我覺得我遺漏了一些微不足道的東西,但我不明白為什么不滿足約束條件。

#include <vector>
#include <ranges>
#include <utility>

template <typename T>
struct is_reference_wrapper : std::false_type {};
template <typename T>
struct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type {};
template <typename T>
inline constexpr bool is_reference_wrapper_v = is_reference_wrapper<T>::value;
template <typename T>
concept ReferenceWrapper = is_reference_wrapper_v<T>;
template <typename T>
concept ReferenceWrapperPair = requires(const T& t) {
    { t.first } -> ReferenceWrapper;
    { t.second } -> ReferenceWrapper;
};
template <typename T>
concept ReferenceWrapperPairRange =
    std::ranges::range<T> && ReferenceWrapperPair<std::ranges::range_value_t<T>>;

int main()
{
    std::vector<std::pair<int, int>> v{ {1,2}, {3,4}, {5,6} };
    auto fn = [](std::pair<int, int>& val) {
        return std::pair{std::reference_wrapper<int>{val.first}, std::reference_wrapper<int>{val.second} };
    };
    /* ReferenceWrapperPairRange */ auto rng = v | std::views::transform(fn);
    /* ReferenceWrapperPair */ auto pair = *(rng.begin());
    ReferenceWrapper auto first = pair.first;
    ReferenceWrapper auto second = pair.second;
    return 0;
}

復合要求{ expression } -> type-constraint要求decltype((expression))必須滿足type-constraint constraint 施加的約束,因為decltype((t.first))將被視為普通的左值表達式,它將導致在 const 左值引用類型中。

你可能想使用 C++23 auto(x)來獲取衰減類型

template <typename T>
concept ReferenceWrapperPair = requires(const T& t) {
    { auto(t.first) } -> ReferenceWrapper;
    { auto(t.second) } -> ReferenceWrapper;
};

或者將ReferenceWrapper概念更改為:

template <typename T>
concept ReferenceWrapper = is_reference_wrapper_v<std::remove_cvref_t<T>>;

暫無
暫無

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

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