I need serious help

I seriously suck at programming. Why won't this compile? I don't understand why it thinks it isn't declared within the scope....

I am using..
g++ --std=c++0x main.cpp
My Errors:
main.cpp: In function ‘int main(int, char**)’:
main.cpp:136:50: error: template argument 2 is invalid
main.cpp:136:50: error: template argument 4 is invalid
main.cpp:138:9: error: ‘mapConstructor’ was not declared in this scope


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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <functional>
#include <map>

#include "Entity.h"
#include "Armor.h"
#include "Weapon.h"
#include "Item.h"
#include "Creature.h"
#include "XMLSerializable.h"

using namespace std;

XMLSerializable * constructItem()
{
        return new Item;
}


void  outputXML(vector<XMLSerializable*> & vObjects, ostream & output)
{


        output << "<?xml version=\"1.0\" encoding = \"utf-8\"?>"
                << endl
                << "<World>"
                << endl;

        for( auto it = vObjects.begin();
           it != vObjects.end();
           it++ )
        {
          (*it)->writeFragment(output);
        }

        output << "</World>" << endl;
}

void dumpObjects(vector<XMLSerializable*> & vObjects)
{
    for( auto it = vObjects.begin();
        it != vObjects.end();
        it++)
{
        (*it)->dumpObject();
        cout << endl;
}

}

void parseElement(istream & input, string sPrefix)
{
  string sElementName;
        getline(input, sElementName, '>');

        if( sElementName.back() == '/' )
        {
                cout << sPrefix << "Empty element: " << sElementName << endl;
                return;
        }
        else
        {
                cout << sPrefix << "Element - " << sElementName << endl;
        }

        string sContent = "";


        while( true )
        {

                char c = input.get();

                while( c != '<' )
                {
                        if( c != '\n' )
                                sContent.push_back(c);

                        c = input.get();
                }

                if( input.peek() == '/' )
                {
                        input.get();
     }

                if( input.peek() == '/' )
                {
                        input.get();
                        string sEndElement;
                        getline(input, sEndElement, '>');

                        if( sEndElement != sElementName )
                                cout << "Bad XML found" << endl;


                        cout << sPrefix << "Content - " << sContent << endl;

                        return;
                }
                else
                {
                        parseElement(input, sPrefix + "  ");
                }

        }

}

void parseXML(string sFilename)
{
        ifstream input;
        input.open(sFilename);

        while( input.get() != '?' );
        while( input.get() != '?' );

        if( input.get() != '>' )
        {
         cout << "Bad XML detected" << endl;
                return;
        }

        while( input.get() != '<' );


        parseElement(input, "");

}

int main(int argc, char * argv[])
{




        map<string, function<XMLSerializable*()> mapConstructor;

        mapConstructor["Item"] = constructItem();

        mapConstructor["Weapon"] = []() { return new Weapon; };
        mapConstructor["Armor"] = []() { return new Armor; };
        mapConstructor["Creature"] = []() { return new Creature; };

        string sLookup;
        cout << "What class do you want to look up? " << endl;
        cin >> sLookup;

        function<XMLSerializable*()> pFunc = mapConstructor[sLookup];
 if(pFunc == NULL)
        {
          cout << "Class" << sLookup << " not found. " << endl;
        }
        else
        {
          XMLSerializable * pObject = pFunc();

                if (pObject == NULL)
                {
                        cout << "Couldn't construct object. " << endl;
                }
                else
                {
                        cout << "Object constructed." << endl;
                }

        }


        cout << "What file should we parse? ";
        string sFilename;
        cin >> sFilename;

        parseXML(sFilename);
       return 0;
}


I think you need another ">" in line 140
Ok I did that. And Now I got this Error:

/usr/include/c++/4.6/functional: In static member function ‘static _Res std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes ...) [with _Res = XMLSerializable*, _Functor = XMLSerializable*, _ArgTypes = {}]’:
/usr/include/c++/4.6/functional:2148:6: instantiated from ‘std::function<_Res(_ArgTypes ...)>::function(_Functor, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type) [with _Functor = XMLSerializable*, _Res = XMLSerializable*, _ArgTypes = {}, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type = std::function<XMLSerializable*()>::_Useless]’
/usr/include/c++/4.6/functional:2024:4: instantiated from ‘typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>&>::type std::function<_Res(_ArgTypes ...)>::operator=(_Functor&&) [with _Functor = XMLSerializable*, _Res = XMLSerializable*, _ArgTypes = {}, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>&>::type = std::function<XMLSerializable*()>&]’
main.cpp:138:48: instantiated from here
/usr/include/c++/4.6/functional:1764:40: error: ‘* std::_Function_base::_Base_manager<_Functor>::_M_get_pointer [with _Functor = XMLSerializable*]((* & __functor))’ cannot be used as a function



All I am trying to do is output my information from my .h and .cpp files that are all inheriting/deriving from a base XMLSerializable.h file.
As far as I can understand from the error message, the problem seems to be related to the line:

 
map<string, function<XMLSerializable*()>> mapConstructor;


I don't know why, but it seems you cannot use std::function<T> as a parameter of a template class/function. Or at least this is what I understood from reading this page:

http://stackoverflow.com/questions/13661391/why-isnt-stdfunction-a-valid-template-parameter-while-a-function-pointer-is

Another page I found that it could help you is this one:

http://stackoverflow.com/questions/7624017/c0x-storing-any-type-of-stdfunction-in-a-stdmap

I am not enough good to really help you but I hope those links could help you to fix your problem

You need a space between the 2 '>' otherwise the compiler thinks you're using the input operator ">>"


Instead of ">>" use "> >"

i.e. instead of

map<string, function<XMLSerializable*()>> mapConstructor;

Do

map<string, function<XMLSerializable*()> > mapConstructor;
As far as compiler can distinguish when "*" is a multiplier or when it marks a pointer, it can also understand that >> is to be interpreted as two > > instead of operator >> when > is expected to make template have sense (remember also that in that position operator >> wouldn't have any sense).

So I think is not a real problem.
However the hint could be a nice suggestion in order to have a nicer code to look at :)
@nobun

Your conclusion is right, I had fallen into my old C++98 ways :)

Your logic is however flawed. A conforming c++98 compiler can tell the difference between a pointer and the multiplication operator, but it still throws a wobbly when you hit it with "vector<vector<int>>"

(remember also that in that position operator >> wouldn't have any sense).

Stuff doesn't compile, for the very reason that it doesn't make sense.
Last edited on
thanks guys! Now I'm getting this error message tho! What in the world does this mean?
g++ --std=c++0x main.cpp
/tmp/ccXkVpnY.o: In function `constructItem()':
main.cpp:(.text+0x18): undefined reference to `Item::Item()'
/tmp/ccXkVpnY.o: In function `main::{lambda()#1}::operator()() const':
main.cpp:(.text+0x610): undefined reference to `Item::Item()'
/tmp/ccXkVpnY.o: In function `main::{lambda()#2}::operator()() const':
main.cpp:(.text+0x656): undefined reference to `Weapon::Weapon()'
/tmp/ccXkVpnY.o: In function `main::{lambda()#3}::operator()() const':
main.cpp:(.text+0x69c): undefined reference to `Armor::Armor()'
/tmp/ccXkVpnY.o: In function `main::{lambda()#4}::operator()() const':
main.cpp:(.text+0x6e2): undefined reference to `Creature::Creature()'
collect2: ld returned 1 exit status


Here is my code, It's been revised a bit.

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <functional>
#include <map>

#include "Consumable.h"
#include "Equipment.h"
#include "Character.h"
#include "Player.h"
#include "Entity.h"
#include "Armor.h"
#include "Weapon.h"
#include "Item.h"
#include "Creature.h"
#include "XMLSerializable.h"

using namespace std;

XMLSerializable * constructItem()
{
        return new Item;
}


void  outputXML(vector<XMLSerializable*> & vObjects, ostream & output)
{


        output << "<?xml version=\"1.0\" encoding = \"utf-8\"?>"
                << endl
                << "<World>"
                << endl;

        for( auto it = vObjects.begin();
           it != vObjects.end();
           it++ )
 {
          (*it)->writeFragment(output);
        }

        output << "</World>" << endl;
}

void dumpObjects(vector<XMLSerializable*> & vObjects)
{
    for( auto it = vObjects.begin();
        it != vObjects.end();
        it++)
{
        (*it)->dumpObject();
        cout << endl;
}

}

void parseElement(istream & input, string sPrefix)
{
        string sElementName;
        getline(input, sElementName, '>');

        if( sElementName.back() == '/' )
        {
                cout << sPrefix << "Empty element: " << sElementName << endl;
                return;
        }
        else
        {
                cout << sPrefix << "Element - " << sElementName << endl;
        }

        string sContent = "";
  while( true )
        {

                char c = input.get();

                while( c != '<' )
                {
                        if( c != '\n' )
                                sContent.push_back(c);

                        c = input.get();
                }

                if( input.peek() == '/' )
                {
                        input.get();
                        string sEndElement;
                        getline(input, sEndElement, '>');

                        if( sEndElement != sElementName )
                                cout << "Bad XML found" << endl;


                        cout << sPrefix << "Content - " << sContent << endl;

                        return;
                }
                else
                {
                        parseElement(input, sPrefix + "  ");
                }

        }

}

void parseXML(string sFilename)
{
        ifstream input;
        input.open(sFilename);

        while( input.get() != '?' );
        while( input.get() != '?' );

        if( input.get() != '>' )
        {
                cout << "Bad XML detected" << endl;
                return;
        }

        while( input.get() != '<' );


        parseElement(input, "");

}

int main(int argc, char * argv[])
{




        map<string, function<XMLSerializable*()>> mapConstructor;

        mapConstructor["Item"] = []() {return new Item; };

        mapConstructor["Weapon"] = []() { return new Weapon; };
        mapConstructor["Armor"] = []() { return new Armor; };
        mapConstructor["Creature"] = []() { return new Creature; };

        string sLookup;
        cout << "What class do you want to look up? " << endl;
        cin >> sLookup;
 function<XMLSerializable*()> pFunc = mapConstructor[sLookup];



        if(pFunc == NULL)
        {
          cout << "Class" << sLookup << " not found. " << endl;
        }
        else
        {
          XMLSerializable * pObject = pFunc();

                if (pObject == NULL)
                {
                        cout << "Couldn't construct object. " << endl;
                }
                else
                {
                        cout << "Object constructed." << endl;
                }

        }


        cout << "What file should we parse? ";
        string sFilename;
        cin >> sFilename;

        parseXML(sFilename);



        return 0;
}

How are you calls to the mapped functions parenthesized in Item::Item(), etc.?
like this.. (This is the Item.cpp file) NOTE: This isn't all of the code in the Item.cpp. I was just posting some so you could see how they are parenthesized. Any clue?


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
38
#include "Item.h"

Item::Item()
{
        m_iWeight = 0;
        m_iValue = 0;
}

void Item::setWeight(int iWeight)
{
        m_iWeight = iWeight;
}

int Item::getWeight()
{
        return m_iWeight;
}

void Item::setValue(int iValue)
{
        m_iValue = iValue;
}


int Item::getValue()
{
        return m_iValue;
}

void Item::dumpObjectData()
{
        Entity::dumpObjectData();

        std::cout << "   Weight  : " << getWeight() << std::endl;
        std::cout << "    Value  : " << getValue() << std::endl;
}

void Item::dumpObject()
The problem is that the command you gave was to try to build an executable. It failed in the link, because it could not find Item.o, etc.. Try adding the -c flag to just compile an object file. Then link all the object files together.
Last edited on
Topic archived. No new replies allowed.