"no matching function for call to 'begin(int&)'"

S

Stefan Ram

#include <iostream>
#include <ostream>

int begin( int & ){ return 1; }
int end( int & e ){ return e; }

int main(){ for( int i : 5 )::std::cout << i << '\n'; }

Error: no matching function for call to 'begin(int&)'

Can I make C++ call my custom begin and end functions
for the loop above? As you can see, my first attempt
does not seem to work.
 
V

Victor Bazarov

#include <iostream>
#include <ostream>

int begin( int & ){ return 1; }
int end( int & e ){ return e; }

int main(){ for( int i : 5 )::std::cout << i << '\n'; }

Error: no matching function for call to 'begin(int&)'

Can I make C++ call my custom begin and end functions
for the loop above? As you can see, my first attempt
does not seem to work.

A reference to non-const int (the argument to 'begin' and 'end') cannot
be bound to a temporary object (in your case the literal 5 is the
temporary). A reference to const int *can*.

V
 
V

Victor Bazarov

A reference to non-const int (the argument to 'begin' and 'end') cannot
be bound to a temporary object (in your case the literal 5 is the
temporary). A reference to const int *can*.

.... although I am not sure it's the end of your problems, though. Need
to look at the 'begin' and 'end' requirements to be sure...

V
 
S

Stefan Ram

Victor Bazarov said:
A reference to non-const int (the argument to 'begin' and 'end') cannot
be bound to a temporary object (in your case the literal 5 is the
temporary). A reference to const int *can*.

Yeah, but it's *the compiler* who says that he wants
to have a function »begin(int&)«, so I tried to give
him such a function, but he does not accept it.

You might describe another error, but this other
error should not give the above error message.

(I now believe that I will not get this to work,
because the begin and end functions are supposed
to return some pointer or iterator - so that would be
yet another error. But then, the compiler should
complain about the return type, which is not what
the above error message is about.)
 
V

Victor Bazarov

Yeah, but it's *the compiler* who says that he wants
to have a function »begin(int&)«, so I tried to give
him such a function, but he does not accept it.

You might describe another error, but this other
error should not give the above error message.

(I now believe that I will not get this to work,
because the begin and end functions are supposed
to return some pointer or iterator - so that would be
yet another error. But then, the compiler should
complain about the return type, which is not what
the above error message is about.)

I got this code to compile with VC++ 2012:
8<=====================================================
#include <iostream>

namespace std {
const int* begin( const int& i)
{
std::cout << "begin(" << i << ")";
return &i;
}

const int* end( const int& e)
{
std::cout << "end(" << e << ")";
return &e;
}
}

int main()
{
for ( int i : 5 )
{
std::cout << "inside for i=" << i << '\n';
}
}

8<=====================================================
but if you look, since both 'begin' and 'end' return the same address,
the loop does not execute even once. If you want it to run once with
the given value, you will need to make 'end' return a pointer that
follows the address of that temporary, which is tricky to say the least.

It can be done with static variables, but it's not thread-safe. You
could probably play some trick with special class, but is it worth it?

V
 
Ö

Öö Tiib

#include <iostream>
#include <ostream>

int begin( int & ){ return 1; }
int end( int & e ){ return e; }

int main(){ for( int i : 5 )::std::cout << i << '\n'; }

As I read standard you have to return a thing from 'begin' and 'end'
that has assignment operator, prefix increment operator, operator!=,
and dereference operator (unary *) for that range-based-for to work.
Plain 'int' lacks unary * so it can't work.
Error: no matching function for call to 'begin(int&)'

Can I make C++ call my custom begin and end functions
for the loop above? As you can see, my first attempt
does not seem to work.

You have perhaps to make custom iterator class for iterating over
ints (that has at least the operators that I did list).
 
S

SG

[...]
Error: no matching function for call to 'begin(int&)'
[...]
Can I make C++ call my custom begin and end functions
for the loop above? As you can see, my first attempt
does not seem to work.

Built-in types don't have associated namespaces. So, there is no
argument-dependend lookup. For the purpose of lookup the for range
loops looks for begin/end member functions and if they are not
available looks for free begin/end functions via ADL where the
namespace ::std is always considered part of the associated namespaces
(so the for range loop works for raw arrays).

And secondly, begin and end are supposed to return things that are
iterator-like. If you want to write begin/end functions that work in
a for-range loop, the things returned by begin/end have to be usable
like iterators. That means operator++ advances it, operator* yields
the current value and ==/!= are needed for comparison.

Here's a quick sketch:

struct intiter
{
int value;
explicit intiter(int v) : value(v) {}
int operator*() const {return value;}
intiter& operator++() {++value; return *this;}
bool operator==(intiter that) const {return value==that.value;}
bool operator!=(intiter that) const {return value!=that.value;}
};

struct intrange
{
int beg_, end_;
intrange(int b, int e) : beg_(b), end_(e) {}
intiter begin() const {return intiter(beg_);}
intiter end() const {return intiter(end_);}
};

#include <iostream>

int main()
{
for (int i : intrange(0,5)) {
std::cout << i << std::endl;
}
}

Cheers!
sg
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top