gpt4 book ai didi

c++ - 从 back_insert_iterator 中提取容器的 value_type 的特征类

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:21:14 27 4
gpt4 key购买 nike

std::back_insert_iteratorvalue_type 等于 void,但它还有一个 protected 成员 container 包含指向底层 Container 的指针。我正在尝试编写一个 traits 类来提取容器的 value_type,如下所示:

#include <iterator>
#include <type_traits>
#include <vector>

template<class OutputIt>
struct outit_vt
:
OutputIt
{
using self_type = outit_vt<OutputIt>;
using value_type = typename std::remove_pointer_t<decltype(std::declval<self_type>().container)>::value_type;
};

int main()
{
std::vector<int> v;
auto it = std::back_inserter(v);
static_assert(std::is_same<outit_vt<decltype(it)>::value_type, int>::value, "");
}

Live Example

但是,这(或多或少是意料之中的)会遇到不完整的类型错误。为了提取容器的 value_type 是否有任何办法?

最佳答案

@Rapptz 的答案是正确的,但对于通用代码(即当先验不清楚是否处理原始 T*back_insert_iterator 或标准库的其他输出迭代器之一时),更多系统的方法是必要的。

为此,下面定义了一个类模板 output_iterator_traits在用户定义的 namespace xstd 中.

#include <iterator>             // iterator, iterator_traits, input_iterator_tag, output_iterator_tag, random_access_iterator_tag
// back_insert_iterator, front_insert_iterator, insert_iterator, ostream_iterator, ostreambuf_iterator
#include <memory> // raw_storage_iterator

namespace xstd {

template<class T>
struct output_iterator_traits
:
std::iterator_traits<T>
{};

template< class OutputIt, class T>
struct output_iterator_traits<std::raw_storage_iterator<OutputIt, T>>
:
std::iterator<std::output_iterator_tag, T>
{};

template<class Container>
struct output_iterator_traits<std::back_insert_iterator<Container>>
:
std::iterator<std::output_iterator_tag, typename Container::value_type>
{};

template<class Container>
struct output_iterator_traits<std::front_insert_iterator<Container>>
:
std::iterator<std::output_iterator_tag, typename Container::value_type>
{};

template<class Container>
struct output_iterator_traits<std::insert_iterator<Container>>
:
std::iterator<std::output_iterator_tag, typename Container::value_type>
{};

template <class T, class charT, class traits>
struct output_iterator_traits<std::ostream_iterator<T, charT, traits>>
:
std::iterator<std::output_iterator_tag, T>
{};

template <class charT, class traits>
struct output_iterator_traits<std::ostreambuf_iterator<charT, traits>>
:
std::iterator<std::output_iterator_tag, charT>
{};

} // namespace xstd

非专用版本简单地继承自std::iterator_traits<T> , 但对于 <iterator> 中定义的 6 个输出迭代器和 <memory> header ,特化继承自 std::iterator<std::output_iterator_tag, V>其中 V是作为迭代器的 operator=(const V&) 的参数出现的类型.

对于插入迭代器,这对应于 typename Container::value_type , 对于原始存储迭代器到 T , 以及 ostreamostreambuf T 的迭代器和 charT , 分别。

形式的通用算法

template<class InputIt, class OutputIt>
auto my_fancy_algorithm(InputIt first, InputIt last, OutputIt dest)
{
using T = typename xstd::output_iterator_traits<OutputIt>::value_type;
for (; first != last; ++first) {
// ... construct arguments from *first
*dest++ = T{ /* arguments */ };
}
}

然后将透明地使用原始指针和标准库的输出迭代器。

关于c++ - 从 back_insert_iterator 中提取容器的 value_type 的特征类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29065760/

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