Structures problem

Hi,

I don't have a lot of experience using structures and I think that's why I don't understand where I mess it up :/
I get an error saying there's no matching function call, but to me it seems to be alright...

I'm trying to set up some sort of differential synchronisation. In order to compare the current files to the ones that were there at the last run I plan to put them in a map and use their path (including filename) as key.
Here's a selection of the code that matters (imo):


main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
include string, map, time.h, log.h,...

struct historyData{
	std::string name;
	off_t size;
	time_t mTime;};

int main()
{
	std::map<std::string, historyData> * historyTable;
	log * history = new log("/home/USER/historyLog.txt", historyTable);
//ERROR: no matching function for call to ‘log::log(const char [28], std::map<std::basic_string<char>, historyData>*&)’

	...
}


log.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef LOG_H
#define LOG_H

class log
{
public:
    std::string path;
    std::map<std::string, historyData> * historyTable;

    log(std::string, std::map<std::string,historyData> *);
    void read();
};

#endif // LOG_H 


log.cpp
1
2
3
4
5
6
7
#include "log.h"

log::log(std::string path_in, std::map<std::string, historyData> * historyTable_in)
{
    path = path_in;
    historyTable = historyTable_in;
}
The error indicates that the compiler is looking for a function matching this:

log::log(const char [28], std::map<std::basic_string<char>, historyData>*&)

So it's looking for a constructor for the log object that takes three arguments, where the first argument is an object of type const char [28] and the second is an object of type std::map<std::basic_string<char>, historyData>*&).

What have you written? A function very similar:
log::log(std::string path_in, std::map<std::string, historyData> * historyTable_in)
but with a difference. The function you wrote takes in a std::string as the first object, not a const char [28].

So here, when you try to call it:
new log("/home/USER/historyLog.txt", historyTable);
you need to change that const char[28] for a std::string.


All that said, what are you using to compile this? My compiler happily does the conversion without complaining.
Last edited on
@moschops - I disagree.

string has a const char * constructor and the compiler will happily generate a string to pass to the OP's log constructor. Effectively:
new log(string("/home/USER/historyLog.txt"), historyTable);

I received no errors when compiling the OP's code in Visual Studio.
I received no errors when compiling the OP's code in Visual Studio.


And I got none ( My compiler happily does the conversion without complaining. )

Nonetheless, the OP stated that that's the line in question, and the error message is pretty unequivocal. Possibly some ancient compiler that won't transform the string literal into a std::string? I'm not sure where the value 28 comes into it either.
I've copied the code into QtCreator, but it still doesn't work (even after putting the text in a std::string variable).
the current error: 'historyData' was not declared in this scope
It does work when I change historyData into an int, so I still think it has got something to do with this structure.

I use geany (on Ubuntu 12.04) which uses g++ -Wall -c "%f" as build command, this compiler doesn't give any problems when nog putting the text in a string variable.
Here's all the code I used and got the error with:

main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <map>
#include <string>
#include <time.h>
#include "log.h"

struct historyData{
    std::string name;
    off_t size;
    time_t mTime;};

int main()
{
    std::map<std::string, historyData /*int*/> * historyTable;
    Log * history = new Log("/home/USER/historyLog.txt", historyTable);

    return 0;
}


log.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef LOG_H
#define LOG_H

#include <string>
#include <map>

class Log
{
public:
    std::string path;
    std::map<std::string, historyData /*int*/> * historyTable;

    Log(std::string, std::map<std::string,historyData /*int*/> * );
};

#endif // LOG_H 


log.cpp
1
2
3
4
5
6
7
#include "log.h"

Log::Log(std::string path_in, std::map<std::string, historyData /*int*/> * historyTable_in)
{
    path = path_in;
    historyTable = historyTable_in;
}
I can resolve the problem by making a class called historyData, but that doesn't learn me how to use structures :(

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef HISTORYDATA_H
#define HISTORYDATA_H

#include <string>
#include <time.h>

class historyData
{
public:
    std::string name;
    off_t size;
    time_t mTime;
};

#endif // HISTORYDATA_H 
'Log' needs to know what is an 'historyData'. So the struct definition must be present before.
That's commonly done trough includes, as in your last post.


Apart.
1
2
    std::map<std::string, historyData /*int*/> * historyTable;
    Log * history = new Log("/home/USER/historyLog.txt", historyTable);
'historyTable' is uninitialized.
¿Why are you using pointers?
1
2
    std::map<std::string, historyData /*int*/> historyTable;
    Log history("/home/USER/historyLog.txt", &historyTable);
Last edited on
before what? before the class definition of log? that didn't help much it gave back an error :/
You're right about the pointers, thanks for the tip :-)
The code below compiles. Check it against your code (remember, #include simply copies the #include d file into that spot.


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
#include <string>
#include <map>
struct historyData{
	std::string name;
	int size;
	time_t mTime;};


class log
{
public:
    std::string path;
    std::map<std::string, historyData> * historyTable;

    log(std::string, std::map<std::string,historyData> *);
    void read();
};


log::log(std::string path_in, std::map<std::string, historyData> * historyTable_in)
{
    path = path_in;
    historyTable = historyTable_in;
}



int main()
{
	std::map<std::string, historyData> * historyTable;
	log * history = new log("/home/USER/historyLog.txt", historyTable);

}

Last edited on
Thank you very, VERY, much, now I understand!
It's actually quite easy to understand :)

Now the error I got when I was trying to put another struct definition in the beginning of the log.h file (just above "class log") makes sense to me: it said that that was the first one and the one in my main file the second one, but I didn't figure it out.
You can have your compiler stop after the preprocessor stage and examine what the source code looks like right after it substitutes all the #include d files. Commonly, this is done with the -E switch

e.g.

g++ -E someSouceCode.cpp

will produce a file that is someSourceCode.cpp after all the #include and any other preprocessor directives. Sometimes, this is helpful so you can see exactly what is being put in where.
Topic archived. No new replies allowed.