使用哪个概念来检查迭代器的值类型?

问题描述 投票:0回答:1

我对概念和范围/观点很陌生。

我试图通过传递由迭代器或范围/视图定义的值序列来编写类的初始化。

我能够检查函数参数是迭代器还是范围。但我无法检查迭代器返回的值是否是特定类型。

例如(C++23):

#include <print>
#include <vector>

struct Data {
    int i;
    std::string l;
};

struct DataContainer {
    // iterator version
    // QUESTION: how can I check that I handles "Data"?
    template<std::input_iterator I, std::sentinel_for<I> S>
    void add(I start, S end) {
        for (auto data = start; data != end; ++data) {
            _data.push_back(*data);
        }
    }
    // range/views version
    // QUESTION: how can I check that R handles "Data"?
    template<std::ranges::input_range R>
    void add(R &&r) {
        add(std::begin(r), std::end(r));
    }
    void dump() const {
        for (const auto& d: _data){
            std::print("[{},'{}'], ", d.i, d.l);
        }
        std::println();
    }
    std::vector<Data> _data;
};

int main()
{
    std::vector<Data> init{{1, "one"}, {2, "two"}, {3, "three"}};
    {
        DataContainer dc;
        dc.add(init.begin(), init.end());
        dc.dump();
    }
    {
        DataContainer dc;
        dc.add(init);
        dc.dump();
    }
    return 0;
}

如何检查

*start
是否返回
Data

c++ iterator c++-concepts c++23
1个回答
1
投票

在这两种情况下,您都可以添加约束:

template <std::input_iterator I, std::sentinel_for<I> S>
    requires std::convertible_to<std::iter_value_t<I>, Data> // constraint added
void add(I start, S end) {
    // ...
}

template <std::ranges::input_range R>
    requires std::convertible_to<std::iter_value_t<R>, Data> // constraint added
void add(R&& r) {
    // ...
}

std::convertible_to

概念

convertible_to<From, To>
指定与
std::declval<From>()
相同类型和值类别的表达式可以隐式和显式转换为类型
To
,并且两种形式的转换产生相同的结果。

std::iter_value_t

  1. 计算
    T
    的值类型。
  • 如果
    std::iterator_traits<std::remove_cvref_t<T>>
    没有专门化,那么
    std::iter_value_t<T>
    就是
    std::indirectly_readable_traits<std::remove_cvref_t<T>>::value_type
  • 否则就是
    std::iterator_traits<std::remove_cvref_t<T>>::value_type

更轻松的版本可以使用

std::constructible_from
代替
std::convertible_to

© www.soinside.com 2019 - 2024. All rights reserved.