我想知道附加的代码是否正确实现了自定义C ++输入迭代器。
虽然我能够成功编译并获得预期的结果,但我怀疑我是否完全涵盖了所有输入迭代器的概念要求。
我的具体问题:这是你如何实现自定义C ++输入迭代器的?
我已经研究了类似问题的其他答案,并阅读了Josuttis book中的相关部分。不幸的是,这些资源并没有提供更广泛的信息,即使我能够编写“似乎有效”的代码,我也不相信自己的代码。
该示例实现了一个输入迭代器,它在n
中生成[initial, final]
个值;迭代器以众所周知的Matlab函数命名,提供相同的功能:
#include <cstddef> // for std::size_t
#include <iterator> // for std::iterator
#include <iostream> // for std::cout
#include <algorithm> // for std::copy
#include <vector> // for std::vector
template<typename T = double>
class linspace_iterator
: public std::iterator<std::input_iterator_tag,T> {
public:
/// @brief Constructs the end-of-linspace iterator.
explicit linspace_iterator()
: m_initial(0),
m_final(0),
m_step(0),
m_N(0),
m_k(0) { }
/// @brief Constructs an iterator yielding N equally-spaced values
/// in @p [initial, final].
explicit linspace_iterator(T initial, T final, std::size_t N = 100)
: m_initial(std::move(initial)),
m_final(std::move(final)),
m_step((final - initial) / (N - 1)),
m_N(std::move(N)),
m_k(0) { }
T operator*() const {
return m_initial + m_k * m_step;
}
linspace_iterator<T>& operator++() {
m_k++;
return *this;
}
linspace_iterator<T>& operator++(int n) {
m_k += n;
return *this;
}
bool operator !=(linspace_iterator<T>&) const { return m_k != m_N; }
bool operator ==(linspace_iterator<T>&) const { return m_k == m_N; }
private:
const T m_initial;
const T m_final;
const T m_step;
const std::size_t m_N;
std::size_t m_k;
};
template<typename Container>
Container linspace(typename Container::value_type initial,
typename Container::value_type final,
std::size_t N = 100) {
return Container(linspace_iterator<typename Container::value_type>(initial, final, N),
linspace_iterator<typename Container::value_type>());
}
template<typename Container>
inline void show(const Container& c) {
for(const auto & item : c) {
std::cout << item << " ";
}
std::cout << std::endl;
}
int main() {
std::cout << "Copy linspace to std::cout (5 values in [0, 7])" << std::endl;
std::copy(linspace_iterator<>(0, 7, 5),
linspace_iterator<>(),
std::ostream_iterator<double>(std::cout, ", "));
std::cout << "A vector with 100 values in [-1, 1]" << std::endl;
std::vector<double> data(linspace_iterator<>(-1, 1),
linspace_iterator<>());
show(data);
std::cout << "A vector with 100 values in [-5.0f, 2.0f]" << std::endl;
auto myvec = linspace<std::vector<float>>(-5.0f, 2.0f);
show(myvec);
std::cout << "Addressing @mythagel's comment" << std::endl;
for(auto it = linspace_iterator<>(0, 7, 5), end = linspace_iterator<>(); it != end; ++it) {
std::cout << *it << ' ' << *it << '\n';
}
return 0;
}
使用以下命令:
{cxx} linspace-itertor.cpp -std=c++11 -Wall -Wextra -Werror -pedantic
(其中{cxx}
= g++
4.8.2,icpc
14.0.2和clang++
3.6.0)代码编译成功(没有警告,没有错误)
输出:
Copy linspace to std::cout (5 values in [0, 7])
0, 1.75, 3.5, 5.25, 7, A vector with 100 values in [-1, 1]
-1 -0.979798 -0.959596 -0.939394 -0.919192 -0.89899 -0.878788 -0.858586 -0.838384 -0.818182 -0.79798 -0.777778 -0.757576 -0.737374 -0.717172 -0.69697 -0.676768 -0.656566 -0.636364 -0.616162 -0.59596 -0.575758 -0.555556 -0.535354 -0.515152 -0.494949 -0.474747 -0.454545 -0.434343 -0.414141 -0.393939 -0.373737 -0.353535 -0.333333 -0.313131 -0.292929 -0.272727 -0.252525 -0.232323 -0.212121 -0.191919 -0.171717 -0.151515 -0.131313 -0.111111 -0.0909091 -0.0707071 -0.0505051 -0.030303 -0.010101 0.010101 0.030303 0.0505051 0.0707071 0.0909091 0.111111 0.131313 0.151515 0.171717 0.191919 0.212121 0.232323 0.252525 0.272727 0.292929 0.313131 0.333333 0.353535 0.373737 0.393939 0.414141 0.434343 0.454545 0.474747 0.494949 0.515152 0.535354 0.555556 0.575758 0.59596 0.616162 0.636364 0.656566 0.676768 0.69697 0.717172 0.737374 0.757576 0.777778 0.79798 0.818182 0.838384 0.858586 0.878788 0.89899 0.919192 0.939394 0.959596 0.979798 1
A vector with 100 values in [-5.0f, 2.0f]
-5 -4.92929 -4.85859 -4.78788 -4.71717 -4.64646 -4.57576 -4.50505 -4.43434 -4.36364 -4.29293 -4.22222 -4.15152 -4.08081 -4.0101 -3.93939 -3.86869 -3.79798 -3.72727 -3.65657 -3.58586 -3.51515 -3.44444 -3.37374 -3.30303 -3.23232 -3.16162 -3.09091 -3.0202 -2.9495 -2.87879 -2.80808 -2.73737 -2.66667 -2.59596 -2.52525 -2.45455 -2.38384 -2.31313 -2.24242 -2.17172 -2.10101 -2.0303 -1.9596 -1.88889 -1.81818 -1.74747 -1.67677 -1.60606 -1.53535 -1.46465 -1.39394 -1.32323 -1.25253 -1.18182 -1.11111 -1.0404 -0.969697 -0.89899 -0.828283 -0.757576 -0.686869 -0.616162 -0.545455 -0.474748 -0.404041 -0.333333 -0.262627 -0.191919 -0.121212 -0.0505052 0.0202017 0.090909 0.161616 0.232323 0.30303 0.373737 0.444444 0.515152 0.585858 0.656566 0.727273 0.797979 0.868687 0.939394 1.0101 1.08081 1.15152 1.22222 1.29293 1.36364 1.43434 1.50505 1.57576 1.64646 1.71717 1.78788 1.85859 1.92929 2
Addressing @mythagel's comment
0 0
1.75 1.75
3.5 3.5
5.25 5.25
7 7