Is there a compact equivalent to Python range() in C++/STL
In C++11, there's std::iota
:
#include <vector>
#include <numeric> //std::iota
int main() {
std::vector<int> x(10);
std::iota(std::begin(x), std::end(x), 0); //0 is the starting number
}
C++20 introduced a lazy version (just like Python) as part of the ranges library:
#include <iostream>
#include <ranges>
namespace views = std::views;
int main() {
for (int x : views::iota(0, 10)) {
std::cout << x << ' '; // 0 1 2 3 4 5 6 7 8 9
}
}
C++ range/xrange equivalent in STL or boost?
Boost has counting_iterator as far as I know, which seems to allow only incrementing in steps of 1. For full xrange functionality you might need to implement a similar iterator yourself.
All in all it could look like this (edit: added an iterator for the third overload of xrange, to play around with boost's iterator facade):
#include <iostream>
#include <boost/iterator/counting_iterator.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/foreach.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <cassert>
template <class T>
boost::iterator_range<boost::counting_iterator<T> > xrange(T to)
{
//these assertions are somewhat problematic:
//might produce warnings, if T is unsigned
assert(T() <= to);
return boost::make_iterator_range(boost::counting_iterator<T>(0), boost::counting_iterator<T>(to));
}
template <class T>
boost::iterator_range<boost::counting_iterator<T> > xrange(T from, T to)
{
assert(from <= to);
return boost::make_iterator_range(boost::counting_iterator<T>(from), boost::counting_iterator<T>(to));
}
//iterator that can do increments in steps (positive and negative)
template <class T>
class xrange_iterator:
public boost::iterator_facade<xrange_iterator<T>, const T, std::forward_iterator_tag>
{
T value, incr;
public:
xrange_iterator(T value, T incr = T()): value(value), incr(incr) {}
private:
friend class boost::iterator_core_access;
void increment() { value += incr; }
bool equal(const xrange_iterator& other) const
{
//this is probably somewhat problematic, assuming that the "end iterator"
//is always the right-hand value?
return (incr >= 0 && value >= other.value) || (incr < 0 && value <= other.value);
}
const T& dereference() const { return value; }
};
template <class T>
boost::iterator_range<xrange_iterator<T> > xrange(T from, T to, T increment)
{
assert((increment >= T() && from <= to) || (increment < T() && from >= to));
return boost::make_iterator_range(xrange_iterator<T>(from, increment), xrange_iterator<T>(to));
}
int main()
{
BOOST_FOREACH(int i, xrange(10)) {
std::cout << i << ' ';
}
BOOST_FOREACH(int i, xrange(10, 20)) {
std::cout << i << ' ';
}
std::cout << '\n';
BOOST_FOREACH(int i, xrange(0, 46, 5)) {
std::cout << i << ' ';
}
BOOST_FOREACH(int i, xrange(10, 0, -1)) {
std::cout << i << ' ';
}
}
As others are saying, I don't see this buying you much over a normal for loop.
What's the equivalent to Mathematica's Range[] function in C++?
None in the standard library, but from boost::range
:
#include <iostream>
#include <iterator>
#include <boost/range/irange.hpp>
#include <boost/range/algorithm/copy.hpp>
int main()
{
boost::copy(boost::irange(0, 11),
std::ostream_iterator<int>(std::cout, " "));
}
Output:
0 1 2 3 4 5 6 7 8 9 10
Python-like loop enumeration in C++
As @Kos says, this is such a simple thing that I don't really see the need to simplify it further and would personally just stick to the traditional for loop with indices, except that I'd ditch std::vector<T>::size_type
and simply use std::size_t
:
for(std::size_t i = 0; i < v.size(); ++i)
foo(v[i], i);
I'm not too keen on solution 2. It requires (kinda hidden) random access iterators which wouldn't allow you to easily swap the container, which is one of the strong points of iterators. If you want to use iterators and make it generic (and possibly incur a performance hit when the iterators are not random access), I'd recommend using std::distance
:
for(auto it(v.begin()); it != v.end(); ++it)
foo(*it, std::distance(it, v.begin());
n={0,1,...,n-1} in C++
It can't be done. From section 6.5.4 of the draft of the C++ 14 standard (but C++11 will be very similar)
begin-expr and end-expr are determined as follows:
(1.1) — if _
RangeT
is an array type, [...];
Well, this one obviously doesn't apply. An int
isn't an array
(1.2) — if _RangeT is a class type, [...]
Nope, this doesn't apply either.
(1.3) — otherwise, begin-expr and end-expr are
begin(__range)
andend(__range)
, respectively,
Oo! This looks hopeful. You may need to move begin
and end
into the global namespace, but still...
where
begin
andend
are looked up in the associated namespaces (3.4.2). [ Note: Ordinary unqualified lookup (3.4.1)
is not performed. — end note ]
(emphasis mine). Bother! There aren't any namespaces associated with int
. Specifically, from section 3.4.2
— If T [
int
in our case] is a fundamental type, its associated sets of namespaces and classes are both empty.
The only workround is to write a class range
which has a suitable begin and end method. Then you could write the very pythonic:
for (int i : range(5))
How to use functor which returns two value with standard library functions?
is possible to return two values from a functor (for example a tuple)
yes ,it is ,but you need also proper
operator bool()
As I understood, you want something like this:
#include <utility>
#include <algorithm>
#include <iterator>
#include <functional>
struct Pair{
bool b;
uint32_t data;
operator bool()const{
return this->b;
}
const Pair & isIdd(uint32_t p){
if (p == this-> data) this->b = true;
return *this ;
}
Pair(bool b , uint32_t data){
this-> b = b;
this->data = data;
}
};
int main(){
using namespace std::placeholders;
Pair p(0,0);
std::vector<uint32_t> vct {2};
auto it = vct.begin ();
auto b = std::bind(&Pair::isIdd,_1,_2);
std::find_if(vct.begin (),vct.end (),b(p,*it++ ));
}
But what is here is not relevant to the task set as the solution of the equation.
If this fits to you and you really want to use find_if
as this ,turn it into template and somehow store found data.
Most efficient/elegant way to clip a number?
What about boring, old, readable, and shortest yet:
float clip(float n, float lower, float upper) {
return std::max(lower, std::min(n, upper));
}
?
This expression could also be 'genericized' like so:
template <typename T>
T clip(const T& n, const T& lower, const T& upper) {
return std::max(lower, std::min(n, upper));
}
Update
Billy ONeal added:
Note that on windows you might have to define NOMINMAX because they define min and max macros which conflict
Implement C++ template for generating an index sequence with a given range
The way you defined index_range
(before the question was edited) the answer is simply:
template<std::size_t Min, std::size_t Max>
using make_index_range = index_range<Min, Max>;
Which is not very useful.
So I'm going to assume you mean make_index_range<5, 9>
will give index_sequence<5, 6, 7, 8>
, which can be done like this:
#include <utility>
template<std::size_t N, std::size_t... Seq>
constexpr std::index_sequence<N + Seq ...>
add(std::index_sequence<Seq...>)
{ return {}; }
template<std::size_t Min, std::size_t Max>
using make_index_range = decltype(add<Min>(make_index_sequence<Max-Min>()));
Or if you want make_index_range
to be a class template, define add
as above and then:
template<std::size_t Min, std::size_t Max>
struct make_index_range {
using type = decltype(add<Min>(make_index_sequence<Max-Min>()));
};
(But with this you have to use make_index_range<5, 9>::type
so the alias template is probably better, and closer to how make_index_sequence
works.)
Related Topics
Add External Libraries to Cmakelist.Txt C++
How to Write a Std::String to a Utf-8 Text File
C++ Format MACro/Inline Ostringstream
Shared_Ptr<> Is to Weak_Ptr<> as Unique_Ptr<> Is To... What
C++ - Interval Tree Implementation
Why Don't Std::Vector's Elements Need a Default Constructor
How to Print Member Function Address in C++
Using Std::Map<K,V> Where V Has No Usable Default Constructor
Is an Iterator in C++ a Pointer
Does an R Compiler to C/C++ Exist
C++11 Variable Number of Arguments, Same Specific Type
What Does 'Return *This' Mean in C++
Uses for Anonymous Namespaces in Header Files
C++ Concatenate Two Int Arrays into One Larger Array
C++, How to Statically Initialize a Std::Map at Compile Time