I have a problem with declaring a function in one of my header files (C++), this is how the file looks:
#ifndef MACTRANSFERINCLUDE
#define MACTRANSFERINCLUDE
#ifdef USE_MAC
#include <string>
#include <boost/shared_ptr.hpp>
using namespace std;
boost::shared_ptr<wstring> browseFolder();
boost::shared_ptr<vector<wstring>> getFilesInDirRecursiveImplementation(boost::shared_ptr<vector<wstring>> dirs, boost::shared_ptr<vector<wstring>> files);
#endif
#endif
When building the project (for Mac OSX in XCode), I get "'dirs' was not declared in this scope".
If I also declare a function
boost::shared_ptr<vector<wstring>> foo();
I get the error "A function call cannot appear in a constant-expression". I'm not very familiar with C++, so any help would be appreciated.
You need to include header <vector>
#include <vector>
Maybe it is the reason of the error.
I do not see a big difference between declaration
boost::shared_ptr<wstring> browseFolder();
and
boost::shared_ptr<vector<wstring>> foo();
So the compiler should issue error
"A function call cannot appear in a constant-expression".
also for the first declaration.
The only difference is that the second declaration is used vector that was not declared. At least it is not seen where it is declared in your header.
Also it is a bad idea to use directive
using namespace std;
I would remove it and write
boost::shared_ptr<std::wstring> browseFolder();
boost::shared_ptr<std::vector<std::wstring>> getFilesInDirRecursiveImplementation(boost::shared_ptr<std::vector<std::wstring>> dirs, boost::shared_ptr<std::vector<std::wstring>> files);
The other reason is that maybe you need to insert a blank between symbols >> For example
boost::shared_ptr<std::vector<std::wstring> > dirs
It seems indeed that you have an old compiler that does not use the new syntax for the pair of symbols >> in template argument declarations. So you have to insert a blank between these two symbols > >
Related
1) I know a non-const variable is external linkage by default (it's like it's been declared as external more or less) but i don't understand why can't i define a global variable such as int glbl_a in header
//test.h
#ifndef TEST_H
#define TEST_H
int glbl_a=0; //wrong -> "multiple definition of `glbl_a`"
static int st_glbl_a=1; //ok to initialize it in header!
extern int ext_glbl_a; //ok to declare it and define it in test.cpp
#endif
//test.cpp
#include "test.h"
using namespace std;
//st_glbl_a=22; i could use st_glbl_a but it wouldn't affect st_glbl_a in main cause of 'static'
int ext_glbl_a=2; //definition of external gloabal non-const variable
//main.cpp
#include <iostream>
#include "test.h"
using namespace std;
extern int glbl_a; //declaration of glbl_a external
int main(){
cout<<glbl_a;
}
the working version for this program is the one in which I define int glbl_a=0; in test.cpp only and declare extern int glbl_a; in main before using it in output (definition in test.h is just commented, that is there's nothing about glbl_a).
2)the working version doesn't work anymore if I group all definitions/declaretions into a namespace spread onto test.cpp and test.h (MyNamespace) cause of int glbl_a in test.cpp:
//test.h
#ifndef TEST_H
#define TEST_H
namespace MyNamespace{
//extern int glbl_a;
}
#endif
//test.cpp
#include "test.h"
using namespace std;
namespace MyNamespace{
int glbl_a=0;
}
//main.cpp
#include <iostream>
#include "test.h"
using namespace std;
int main(){
cout<<MyNamespace::glbl_a; //wrong -> "'glbl_a' is not a member of 'MyNaspace'"
}
it would work only if I de-comment declaration in test.h, but why?
Problem 1
Including a header effectively pastes the included file into the including file, producing one large file that is then compiled (and, typically, promptly deleted). This means that every including file now has its very own glbl_a. The compiler is happy, but when the linker attempts to put everything together, it finds many equally valid pretenders to the name glbl_a. The linker hates this and doesn't even try to figure out what you're trying to do. It simply spits out an error message and asks that you fix the problem.
Problem 2
test.cpp and main.cpp are different translation units. They compile to produce different, completely independent objects. Neither can see what's in the other, so the fact that MyNamespace::glbl_a exists in test.cpp is lost on main.cpp. When main.cpp is compiled, the compiler builds a list of identifiers declared in the file constructed from main.cpp and all of its included headers. MyNamespace::glbl_ais never declared as of when it is first used (or after for that matter) so the compiler spits out an error message.
Uncommenting the declaration in test.h means the compiler will find MyNamespace::glbl_a in main.cpp and will allow it's use. Since MyNamespace::glbl_a is defined in test.cpp the linker can find one-and-only-one MyNamespace::glbl_a and can successfully link.
extern does not allocate storage. Instead it is a promise to the compiler that the variable being declared will be fully defined and allocated somewhere else, maybe later in the file or in another file. The variable exists, somewhere, and compilation can continue. The linker will call you out as a liar if it cannot find a definition.
More details here: How does the compilation/linking process work?
More on extern: When to use extern in C++ and Storage class specifiers
headers will be included by other files (more than one) thus if you define in header, it will be in each translation unit thus lead to "multiple definition"
I'm using EnumParser from here It compiles fine in VC++, but using gcc I have such error:
./Terminator.o: In function `EnumParser<FieldType>::EnumParser()':
Terminator.cpp:(.text+0x960): multiple definition of `EnumParser<FieldType>::EnumParser()'
./MicexGate.o:MicexGate.cpp:(.text+0xd0): first defined here
./Terminator.o: In function `EnumParser<FieldType>::EnumParser()':
Terminator.cpp:(.text+0x960): multiple definition of `EnumParser<FieldType>::EnumParser()'
./MicexGate.o:MicexGate.cpp:(.text+0xd0): first defined here
./Terminator.o: In function `EnumParser<FieldsetName>::EnumParser()':
It seems EnumParser<FieldType>::EnumParser() appeared in both MicexGate.o and Terminator.o and this is the problem. But i don't know why this is an error and how to fix it.
In my program I define this EnumParser just once in .cpp file in MicexGate static lib project. Terminator depends on MicexGate probably that's why finally EnumParser defined twice. This is how I define EnumParser<FieldType>:
#include "FieldsConverter.h"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <iostream>
#include "ByteArrayReader.h"
#include "Utils.h"
#include "CommonsMicexBridge.h"
#include "InstrumentsStorage.h"
#include <boost/algorithm/string.hpp>
template<> EnumParser<FieldType>::EnumParser()
{
enumMap["Char"] = Char;
enumMap["Integer"] = Integer;
enumMap["Long"] = Long;
enumMap["Fixed"] = Fixed;
enumMap["Price"] = Price;
enumMap["Date"] = Date;
enumMap["Time"] = Time;
}
How can I fix my problem?
My guess is that you haven't declared the explicit specialisation in a header, included in every file that uses the specialisation:
template<> EnumParser<FieldType>::EnumParser();
Without this declaration, the compiler doesn't know that the explicit specialisation exists, so will instantiate an implicit specialisation from the generic template if it needs one. You now have two definitions, resulting (hopefully) in a link error.
Alternatively, as with any function, you can define it in a header as long as you declare it inline to allow definitions in multiple translation unit.
Templates need to be in headers and not in .cpp files.
My question does not link to a direct example, but is more of a question as a whole. When I was coding with C++, I found (after looking through some threads) that in order to use functions from different files that are in the same project, I would either need a header file. So, for example, if I have the main function in a file called "main.cpp" and I wanted to use a function, "prob1()" in another file called "problem1.cpp", I would need to use a header file.
What is confusing me is why I do not have to worry about this for programming in C? When I was programming in C, in order to use functions from different files, I could call the function directly.
Any help/explanation is appreciated. Thanks!
Your C compiler can implicitly declare the function, but you should be doing so yourself. If you turn up the warnings, you'll see something like:
file1.c: warning: implicit declaration of function ‘func_from_f2’
When file1.c is being compiled, this implicit declaration will be used to create an object file and then when linking you have to just hope that the function actually does exist and the declaration is correct so that the object files can be linked together successfully.
If not, the linker will give you an error somewhere along the lines of:
undefined reference to `func_from_f2'
You also don't necessarily need a header file, you can simply include the declaration/prototype of the function in your source file (the #include directive essentially does this for you). ie. the below will work fine without warnings:
file1.c
void func_from_f2(void);
int main(void)
{
func_from_f2();
return 0;
}
file2.c
#include <stdio.h>
void func_from_f2(void)
{
puts("hello");
}
However, it's usually best practice that you do use a header file:
file1.c
#include "file2.h"
int main(void)
{
func_from_f2();
return 0;
}
file2.h
#ifndef FILE2_H
#define FILE2_H
void func_from_f2(void);
#endif
file2.c
#include <stdio.h>
#include "file2.h"
void func_from_f2(void)
{
puts("hello");
}
In C, the compiler will guess the correct prototype if you haven't provided one. It very often guesses wrong, and then your program breaks.
Whether C or C++, it's always a good idea to put forward declarations in a header file that also gets #included into the implementation file, where the compiler can check for mismatch.
I'm getting crazy since i'm not able to define the prototype of a function i'm actually using.
What i'm doing is create an header file called func1.hwhere i define this prototype (that's because i need to invoke this function from some other function implemented elsewhere):
void FileVector(std::vector<Files> &,const char*,bool);
Where Filesis a struct defined in func1.cpp
struct Files{
HANDLE h;
WIN32_FIND_DATA info;
} file;
I have also another function that accept a std::vector<Files> & as input parameter but when i try to compile (using Eclipse C++) i'm getting those errors:
/FileVector.h:11:22: error: variable or field 'FileVector' declared void
..\/FileVector.h:11:17: error: 'vector' is not a member of 'std'
..\/FileVector.h:11:29: error: 'Files' was not declared in this scope
I've tryied to include several directive in the header file..for example declaring the struct in the header and including vector header do the trick but this way i got loads of "multiple definitions/first defined here" error.
What can i do?
EDIT
Now my header looks like:
#ifndef FILEVECTOR_H_
#define FILEVECTOR_H_
#include <vector>
#include <windows.h>
struct Files{
HANDLE h;
WIN32_FIND_DATA info;
};
void FileVector(std::vector<Files> &,const char*,bool);
#endif /* FILEVECTOR_H_ */
At this point, i need to declare another prototype in another header:
void ProcessInput(vector<Files>&);
but i can't use the same trick as above cause i'll have to re-define the Files struct. How can i solve this?
Make sure to include <vector> in your header file. You also mention that the definition of Files is within the cpp file, you should move it to the header as well.
Also place proper header guards to avoid multiple definition errors:
#ifndef MY_HEADER_FILE_GUARD
#define MY_HEADER_FILE_GUARD
... your content here ...
#endif /*MY_HEADER_FILE_GUARD*/
Update:
Simply including filevector.h from your new header would do. However, it looks like Files should be defined in a header of its own and included from the two headers that make use of it.
I am new to this website and I am trying a simple inheritance example in C++.
I checked my code lots of times and I really see nothing wrong with it, however the compilers gives me errors:
my code:
#ifndef READWORDS_H
#define READWORDS_H
using namespace std;
#include "ReadWords.h"
/**
* ReadPunctWords inherits ReadWords, so MUST define the function filter.
* It chooses to override the default constructor.
*/
class ReadPunctWords: public ReadWords {
public:
bool filter(string word);
};
#endif
And the messages I get from the compiler:
ReadPunctWords.h:11: error: expected class-name before '{' token
ReadPunctWords.h:13: error: `string' has not been declared
ReadPunctWords.h:13: error: ISO C++ forbids declaration of `word' with no type
Tool completed with exit code 1
I am really not sure where I get it wrong as it looks just fine to me?
Thank you for any mistakes you might spot.
You need to include string:
#include <string>
That said, don't use using namespace! Especially at file-scope, and definitely not in a header file. Now any unit that includes this file is forced to succumb to everything in the std namespace.
Take that out, and qualify your names:
bool filter(std::string word);
It's arguable more readable, too. Additionally, you should take your string as a const&:
bool filter(const std::string& word);
To avoid having to copy the string unnecessarily. Lastly, your header guards seem off. Should they be changed? As of now, they seem like the same ones that would be used in your other header, which might effectively stop it from being included.
If you define READWORDS_H and then include ReadWords.h, and if that also has:
#ifndef READWORDS_H
#define READWORDS_H
Then nothing in that file will be processed. If that's the case, ReadWords as a class won't be defined, and you cannot inherit from it. Your guard should probably be:
READPUNCTWORDS_H
You need to include <string> and specify the namespace:
#include <string>
using namespace std;
Also, your include guard should probably be named READPUNCHTWORDS_H rather than READWORDS_H.
Edit: On second thought, GMan is right about not putting using namespace in a header file - qualify the string with std::string instead.
This particular form of error is often caused by a type not being defined (at least when the code looks syntactically correct), in this case probably the class ReadWords but maybe also std::string.
You need to include to get std::string, as other posters have written, but also your guard
#ifndef READWORDS_H
#define READWORDS_H
almost certainly conflicts with the guard in ReadWords.h. You need to make sure your guards are distinct in different header files otherwise you will get conflicts like this. You should change the guard to something like
#ifndef READPUNCTWORDS_H
#define READPUNCTWORDS_H
// ...
#endif
In fact, it's better to have even more verbose guards to make sure they don't conflict. We use guards of the form
#ifndef MODULE_OR_PATH_FILE_H_INCLUDED
#define MODULE_OR_PATH_FILE_H_INCLUDED
// ...
#endif
This ensures different modules or libraries with similarly named headers don't conflict, the INCLUDED thing at the end is my own particular foible that makes the guard slightly more readable.
It's also bad practice to place a "using" declaration in a header file, because it places (potentially unwanted or conflicting) symbols in the global namespace everywhere you include the header. Personally, I prefer to retain the namespace for clarity or alias it in cpp files if it's a long one, for example
namespace fs = boost::filesystem;
also looks like something wrong with ReadWords class def (message for line 11)- we need to see .h file
aha - the sentinial def you use prevents the readwords.h include being read
you need
#ifndef _READPUNCTWORDS_H
#define _READPUNCTWORDS_H
I also suspect the include guards. If they are named the same way in both header files, the result should be something like the following when ReadWords.h is pasted into ReadPunctWords.h.
#ifndef READWORDS_H // Is READWORDS_H defined? No, proceeding
#define READWORDS_H // Now it is defined
// Contents of ReadWords.h is pasted in here
#ifndef READWORDS_H // Is READWORDS_H defined? Yes, ignoring the contents of ReadWords.h (skipping til #endif)
#define READWORDS_H
class ReadWords { ... }; // This is never seen by the compiler as the preprocessor removed it
#endif
class ReadPunctWords: public ReadWords { // Error: ReadWords isn't declared...
public:
bool filter(string word);
};
#endif