Tem*_*Rex 6 c++ iterator value-type type-traits inserter
在std::back_insert_iterator具有value_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, "");
}
Run Code Online (Sandbox Code Playgroud)
但是,这(或多或少地预期)会遇到不完整的类型错误.反正这是为了得到容器的提取物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
Run Code Online (Sandbox Code Playgroud)
unspecialized版本只是继承自std::iterator_traits<T>,但是对于在<iterator>和<memory>头文件中定义的6个输出迭代器,特殊化继承自std::iterator<std::output_iterator_tag, V>哪里V出现的类型是迭代器的参数operator=(const V&).
用于插入的迭代器,这对应于typename Container::value_type,对原始存储迭代器T,以及用于ostream和ostreambuf迭代器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 */ };
}
}
Run Code Online (Sandbox Code Playgroud)
然后将透明地使用原始指针和标准库的输出迭代器.
| 归档时间: |
|
| 查看次数: |
866 次 |
| 最近记录: |