How to pass this class as an argument?

So here's what I want to do. I'm looking to generate an empty list and fill them with names via the STL function generate_n. The problem comes with the third argument. I'm looking to use the class SEQ to do the dirty work of generating all of the names that I need. I figure that once the constructor is called, then the operator will be called right after to complete the function and return the value I need into the list. Problem is, I don't know how to pass this to get to the string operator. How would I go about solving this problem? Here's some code.

The Class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  string INIT_VAL = "A1";

class SEQ {
private:
 string id; // name of soldier

public:
 SEQ ( const string& x = INIT_VAL ) : id ( x ) { } // default constructor
 string operator ( ) (string id) { // overloaded function operator
 string tmp = id;
 if ( id [ 1 ] < '9' ) id [ 1 ]++;
 else { id [ 0 ]++; id [ 1 ] = '1'; }
 return tmp; // return next name in order
 }
}; 


I tried this
 
generate_n (L, N, SEQ());


and got these errors:
/usr/include/c++/4.7/bits/stl_algo.h:5111:42: error: no match for ‘operator++’ in ‘++__first’
/usr/include/c++/4.7/bits/stl_algo.h:5113:2: error: no match for call to ‘(SEQ) ()’
prog5.h:19:7: note: candidate is:
prog5.h:25:6: note: SEQ SEQ::operator()(std::string)
prog5.h:25:6: note: candidate expects 1 argument, 0 provided
In file included from /usr/include/c++/4.7/algorithm:63:0,
from prog5.h:6:
/usr/include/c++/4.7/bits/stl_algo.h:5113:2: error: no match for ‘operator*’ in ‘*__first’

I had figured it would go from the constructor which declares x, and then go straight to the operator. What am I doing wrong?
The callable object passed to std::generate_n () is expected to be a nullary callable object (takes no arguments).

This will make it nullary:
1
2
3
4
5
6
string operator ( ) ( /* string id */ ) { // overloaded function operator
 // string tmp = id;
 if ( id [ 1 ] < '9' ) id [ 1 ]++;
 else { id [ 0 ]++; id [ 1 ] = '1'; }
 return /* tmp */ id; // return next name in order
 }


But there is a second problem: the operator()() is not const, it modifies the state of the callable object, and that is not a good idea.

Perhaps you would be better off using std::iota():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <string>
#include <numeric>

struct name
{
    explicit name( std::string str ) : id(str) {}

    operator std::string() const { return id ; }

    name& operator++()
    {
        if( id.size() > 1 )
        {
            if ( id [ 1 ] < '9' ) id [ 1 ]++;
            else
            {
                id [ 0 ]++;
                id [ 1 ] = '1';
            }
        }
        return *this ; // return next name in order
    }

    private: std::string id ;
};


int main()
{
    constexpr std::size_t N = 5 ;
    std::string a[N] ;

    // http://en.cppreference.com/w/cpp/algorithm/iota
    std::iota( a, a+N, name( "A1") ) ;
    for( const auto& s : a ) std::cout << s << '\n' ;
}

http://coliru.stacked-crooked.com/a/bdc4f0f2d7161a62
Hey, thanks for the suggestion. I managed to figure it out and keep the generate_n function. I was generating into a straight list when I should have been generating into the list's iterator. I also made some corrections to the class like you suggested. Code for the class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string INIT_VAL = "A1";

class SEQ {
private:
 string id; // name of soldier

public:
 SEQ (const string& x = INIT_VAL ) : id ( x ) { } // default constructor
 string operator ( ) ( ) { // overloaded function operator
 string tmp = id;
 if ( id [ 1 ] < '9' ) id [ 1 ]++;
 else { id [ 0 ]++; id [ 1 ] = '1'; }
 return tmp; // return next name in order
 }
}; 


But really, most of the problem came from trying to input all of the output from this class into a list instead of an iterator.
Topic archived. No new replies allowed.