gpt4 book ai didi

c++ - 如何创建用于创建循环的新样式?

转载 作者:太空狗 更新时间:2023-10-29 21:35:40 26 4
gpt4 key购买 nike

我想使用宏来创建更简单的源代码

这是我的代码

constexpr auto make_index_sequence_array(size_t i ,std::index_sequence<arg...>) {
return std::array<size_t, sizeof...(arg)> {i+arg...};
}
#define RANGE(start , end) make_index_sequence_array(start,std::make_index_sequence<end-start>{})
#define ZeroTo(end) RANGE(0 , end)
#define Repeat(end) for(auto itr : RANGE(0 , end))

void main() {
vector<int> a = { 1,2,3 };
for (auto row : RANGE(0,a.size()))
cout << std::setw(4) << a[row];
cout << '\n';
}

我知道我可以使用:

void main() {
vector<int> a = { 1,2,3 };
for (auto itr: a)
cout << std::setw(4) << itr;
cout << '\n';
}

但这是一个简单的例子,我想在更多情况下使用这种风格。编译时的错误是:

Error C2975 '_Size': invalid template argument for 'std::make_index_sequence', expected compile-time constant expression

如何使用我的宏?甚至有可能吗?

最佳答案

我的建议是你使用迭代器,我在下面写了一个例子。在 C++ < C++17 中会做这样的事情:

#include <iostream>

template <class T>
struct RangeIter {
RangeIter(T from, T to, T curr ) :
_from(from), _to(to), _curr(curr) {
}

T operator*() const {
return _curr;
}

T operator++() {
++_curr;
return _curr;
}

bool operator==(const RangeIter & other) {
assert(_from == other._from && _to == other._to);
return _curr == other._curr;
}

bool operator!=(const RangeIter & other) {
return !(_curr == other._curr);
}
T _from, _to, _curr;
};

template <class T>
struct Range {
Range(T from, T to) : _from(from), _to(to) {}

RangeIter<T> begin() { return RangeIter<T>(_from, _to, _from); }
RangeIter<T> end() {
return RangeIter<T>(_from, _to, _to);
}

T _from, _to;
};

template <class T>
Range<T> makeRange(T to, T from) {
return Range<T>(to, from);
}

int main() {

for (auto i : makeRange(0, 10)) {
std::cout << i << std::endl;
}
}

对于 C++17,您可以为开始和结束迭代器使用不同的类型,并对此进行改进。你可以使用哨兵。你可以在这里看看:How the new range-based for loop in C++17 helps Ranges TS?

此处仅使用 C++-17 的解决方案:

#include <iostream>


template <class T>
struct RangeSentinel {
RangeSentinel(T stopVal) : _stopVal(stopVal) {}

T _stopVal;
};

template <class T>
struct RangeIter {
RangeIter(T from, T to, T curr) :
_from(from), _to(to), _curr(curr) {
}

T operator*() const {
return _curr;
}

T operator++() {
++_curr;
return _curr;
}

bool operator==(const RangeSentinel<T> & other) {
assert(_from == other._from && _to == other._to);
return _curr == other._stopVal;
}

bool operator!=(const RangeSentinel<T> & other) {
return !(_curr == other._stopVal);
}
T _from, _to, _curr;
};



template <class T>
struct Range {
Range(T from, T to) : _from(from), _to(to) {}

RangeIter<T> begin() { return RangeIter<T>(_from, _to, _from); }
RangeSentinel<T> end() {
return RangeSentinel<T>(_to);
}

T _from, _to;
};

template <class T>
Range<T> makeRange(T to, T from) {
return Range<T>(to, from);
}

int main() {

for (auto i : makeRange(0, 10)) {
std::cout << i << std::endl;
}
}

如您所见,在 C++17 解决方案中,我不需要再次存储 _from 和 _to 变量,因为哨兵是不同的类型。

关于c++ - 如何创建用于创建循环的新样式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41753336/

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