I am new in C++ development , As I learn online about extern variable - I tried it to string variables and its working fine.But I have to work with string variable as its not working.Please look as follow.
globals.h
#include <iostream>
using namespace std;
#ifndef SIMULATIONFILEPARSER_GLOBALS_H
#define SIMULATIONFILEPARSER_GLOBALS_H
//sequence of files to be execute
extern string ipFiles[];
#endif //SIMULATIONFILEPARSER_GLOBALS_H
globals.cpp
#include "../headers/globals.h"
//sequence of files to be execute
string ipFiles[] = {"in.relaxSubstrate", "in.relaxFluid"};
main.cpp
#include <iostream>
#include "Source/headers/globals.h"
int main() {
for (string &ipFileName :ipFiles) {
std::cout << ipFileName << std::endl;
}
return 0;
}
When I try to run this project , It gives following error
C:\Users\king\ClionProjects\SimulationFileParser\main.cpp: In function 'int main()':
C:\Users\king\ClionProjects\SimulationFileParser\main.cpp:5:30: error: range-based 'for' expression of type 'std::__cxx11::basic_string<char> []' has incomplete type
for (string &ipFileName :ipFiles) {
^
CMakeFiles\SimulationFileParser.dir\build.make:61: recipe for target 'CMakeFiles/SimulationFileParser.dir/main.cpp.obj' failed
mingw32-make.exe[3]: *** [CMakeFiles/SimulationFileParser.dir/main.cpp.obj] Error 1
mingw32-make.exe[3]: *** Waiting for unfinished jobs....
mingw32-make.exe[2]: *** [CMakeFiles/SimulationFileParser.dir/all] Error 2
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/SimulationFileParser.dir/all' failed
mingw32-make.exe[1]: *** [CMakeFiles/SimulationFileParser.dir/rule] Error 2
CMakeFiles\Makefile2:78: recipe for target 'CMakeFiles/SimulationFileParser.dir/rule' failed
mingw32-make.exe: *** [SimulationFileParser] Error 2
Makefile:117: recipe for target 'SimulationFileParser' failed
The compiler doesn't complain about a symbol, that's not visible. It's telling you, that the type is incomplete:
range-based 'for' expression of type 'std::__cxx11::basic_string []' has incomplete type
Until the compiler knows the size of the array, it cannot compile the range-based for loop. To change this, you need to declare a complete type. This could be an array with an explicit size, or - and that's the recommended solution - a standard container1:
globals.h
#pragma once
#include <string>
#include <vector>
extern std::vector<std::string> ipFiles;
globals.cpp
std::vector<std::string> ipFiles{"in.relaxSubstrate", "in.relaxFluid"};
You don't have to change main.cpp. But if you want to make it fancy, you could use auto as well as exercising const-correctness:
int main() {
for (const auto& ipFileName : ipFiles) {
std::cout << ipFileName << std::endl;
}
return 0;
}
1 The size of a standard container does not need to be known at compile time. All the compiler needs are the (forward) iterators to begin() and end() of the controlled sequence. An array, on the other hand, doesn't provide those as member functions, and the compiler needs to generate them. It needs to know the size to generate the equivalent of end().
This loop does not know the size of array.
for (string &ipFileName :ipFiles)
Change in global.h
extern string ipFiles[2];
change in global.cpp
string ipFiles[2] = {"in.relaxSubstrate", "in.relaxFluid"};
After this your code should compile properly.
Related
I am new in C++ development , As I learn online about extern variable - I tried it to string variables and its working fine.But I have to work with string variable as its not working.Please look as follow.
globals.h
#include <iostream>
using namespace std;
#ifndef SIMULATIONFILEPARSER_GLOBALS_H
#define SIMULATIONFILEPARSER_GLOBALS_H
//sequence of files to be execute
extern string ipFiles[];
#endif //SIMULATIONFILEPARSER_GLOBALS_H
globals.cpp
#include "../headers/globals.h"
//sequence of files to be execute
string ipFiles[] = {"in.relaxSubstrate", "in.relaxFluid"};
main.cpp
#include <iostream>
#include "Source/headers/globals.h"
int main() {
for (string &ipFileName :ipFiles) {
std::cout << ipFileName << std::endl;
}
return 0;
}
When I try to run this project , It gives following error
C:\Users\king\ClionProjects\SimulationFileParser\main.cpp: In function 'int main()':
C:\Users\king\ClionProjects\SimulationFileParser\main.cpp:5:30: error: range-based 'for' expression of type 'std::__cxx11::basic_string<char> []' has incomplete type
for (string &ipFileName :ipFiles) {
^
CMakeFiles\SimulationFileParser.dir\build.make:61: recipe for target 'CMakeFiles/SimulationFileParser.dir/main.cpp.obj' failed
mingw32-make.exe[3]: *** [CMakeFiles/SimulationFileParser.dir/main.cpp.obj] Error 1
mingw32-make.exe[3]: *** Waiting for unfinished jobs....
mingw32-make.exe[2]: *** [CMakeFiles/SimulationFileParser.dir/all] Error 2
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/SimulationFileParser.dir/all' failed
mingw32-make.exe[1]: *** [CMakeFiles/SimulationFileParser.dir/rule] Error 2
CMakeFiles\Makefile2:78: recipe for target 'CMakeFiles/SimulationFileParser.dir/rule' failed
mingw32-make.exe: *** [SimulationFileParser] Error 2
Makefile:117: recipe for target 'SimulationFileParser' failed
The compiler doesn't complain about a symbol, that's not visible. It's telling you, that the type is incomplete:
range-based 'for' expression of type 'std::__cxx11::basic_string []' has incomplete type
Until the compiler knows the size of the array, it cannot compile the range-based for loop. To change this, you need to declare a complete type. This could be an array with an explicit size, or - and that's the recommended solution - a standard container1:
globals.h
#pragma once
#include <string>
#include <vector>
extern std::vector<std::string> ipFiles;
globals.cpp
std::vector<std::string> ipFiles{"in.relaxSubstrate", "in.relaxFluid"};
You don't have to change main.cpp. But if you want to make it fancy, you could use auto as well as exercising const-correctness:
int main() {
for (const auto& ipFileName : ipFiles) {
std::cout << ipFileName << std::endl;
}
return 0;
}
1 The size of a standard container does not need to be known at compile time. All the compiler needs are the (forward) iterators to begin() and end() of the controlled sequence. An array, on the other hand, doesn't provide those as member functions, and the compiler needs to generate them. It needs to know the size to generate the equivalent of end().
This loop does not know the size of array.
for (string &ipFileName :ipFiles)
Change in global.h
extern string ipFiles[2];
change in global.cpp
string ipFiles[2] = {"in.relaxSubstrate", "in.relaxFluid"};
After this your code should compile properly.
I've looked through a few posts on this same error and it seems this happens when the compiler can't find a constructor that matches the signature?
But I can't rule out the possibility since my case is rather different - it has a __declspec(dllexport) and I'm not sure if this it the culprit causing the problem.
Here is the error message:
yuqiong#yuqiong-G7-7588:/media/yuqiong/DATA/Vignetting_corrector/C++/Vig_Correction/build$ make
Scanning dependencies of target correction
[ 50%] Building CXX object CMakeFiles/correction.dir/Vig_Correction.cpp.o
In file included from /media/yuqiong/DATA/Vignetting_corrector/C++/Vig_Correction/Vig_Correction.cpp:5:0:
/media/yuqiong/DATA/Vignetting_corrector/C++/Vig_Correction/ColorCorrection.hpp:16:10: error: expected constructor, destructor, or type conversion before ‘(’ token
_declspec(dllexport) int VignettingCorrectionUsingRG(unsigned char* pImage, int ht, int wd,
^
/media/yuqiong/DATA/Vignetting_corrector/C++/Vig_Correction/Vig_Correction.cpp: In function ‘int VignettingCorrect(IplImage*)’:
/media/yuqiong/DATA/Vignetting_corrector/C++/Vig_Correction/Vig_Correction.cpp:47:65: error: ‘VignettingCorrectionUsingRG’ was not declared in this scope
int flag=VignettingCorrectionUsingRG(pImageBuffer, sht, swd, vp);
^
CMakeFiles/correction.dir/build.make:62: recipe for target 'CMakeFiles/correction.dir/Vig_Correction.cpp.o' failed
make[2]: *** [CMakeFiles/correction.dir/Vig_Correction.cpp.o] Error 1
CMakeFiles/Makefile2:72: recipe for target 'CMakeFiles/correction.dir/all' failed
make[1]: *** [CMakeFiles/correction.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
Here is my ColorCorrection.hpp file...
#ifndef COLOR_CORRECTION_HPP
#define COLOR_CORRECTION_HPP
#include <vector>
using namespace std;
__declspec(dllexport) int VignettingCorrectionUsingRG(unsigned char* pImage, int ht, int wd, vector<double>& vp);
#endif
Thanks so much for your help in advance...
I've tried the code on Codeblocks and Clion and I'm still getting a redefinition of struct tm error.
#include <iostream>
#include <ctime> // Needed for the true randomization
#include <cstdlib>
using namespace std;
int main ()
{
int xRan;
srand( time(0)); // This will ensure a really randomized number by help of time.
xRan=rand()%15+1; // Randomizing the number between 1-15.
cout << "Shows a random number between 1-15: " << xRan;
return 0;
}
When ever I use the library I get the error. Not sure if theres something
buggy in the minigw include folder or what. Would deleting all my ide's and reinstalling help? Any ideas maybe why?
In file included from c:\mingw\lib\gcc\mingw32\5.3.0\include\c++\ctime:42:0,
from C:\Users\Kelvindavis\CLionProjects\untitled\main.cpp:2:
c:\mingw\include\time.h:172:8: error: redefinition of 'struct tm'
struct tm
^
In file included from
c:\mingw\lib\gcc\mingw32\5.3.0\include\c++\cwchar:44:0,
from
c:\mingw\lib\gcc\mingw32\5.3.0\include\c++\bits\postypes.h:40,
from c:\mingw\lib\gcc\mingw32\5.3.0\include\c++\iosfwd:40,
from c:\mingw\lib\gcc\mingw32\5.3.0\include\c++\ios:38,
from c:\mingw\lib\gcc\mingw32\5.3.0\include\c++\ostream:38from
c:\mingw\lib\gcc\mingw32\5.3.0\include\c++\iostream:39from
C:\Users\Kelvindavis\CLionProjects\untitled\main.cpp:1:
c:\mingw\include\wchar.h:87:8: error: previous definition of 'struct tm'
struct tm {
^
mingw32-make.exe[3]: * [CMakeFiles/untitled.dir/main.cpp.obj] Error 1
CMakeFiles\untitled.dir\build.make:61: recipe for target
'CMakeFiles/untitled.dir/main.cpp.obj' failed
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/untitled.dir/all'
failed
CMakeFiles\Makefile2:78: recipe for target 'CMakeFiles/untitled.dir/rule'
failed
mingw32-make.exe[2]: [CMakeFiles/untitled.dir/all] Error 2
mingw32-make.exe[1]: [CMakeFiles/untitled.dir/rule] Error 2
mingw32-make.exe: * [untitled] Error 2
Makefile:117: recipe for target 'untitled' failed
I'm having a hard time trying to figure out what's happening in my code. Any help would be much appreciated. Here's my header (.cuh) :
#include <map>
#include <string>
#include <iostream>
#include "SINS_constants.cuh"
using namespace std;
class SINS_inputManager
{
public:
static SINS_inputManager& getInstance()
{
static SINS_inputManager SINS_inputManager_singleton;
return SINS_inputManager_singleton;
}
void parse(ifstream& cfgfile); // TODO Better read incoming variables, recognize by type in a single loop : template ?
private:
static SINS_inputManager* SINS_inputManager_singleton;
map<string, string> options;
SINS_inputManager();
~SINS_inputManager();
SINS_inputManager(SINS_inputManager const&); // not defined copy constructor
void operator=(SINS_inputManager const&); // not defined = operator
};
Here's my .cu :
#include "SINS_inputManager.cuh"
void SINS_inputManager::parse(ifstream& cfgfile)
{
cout << "\n";
string id, eq, val;
while(cfgfile >> id >> eq >> val)
{
if (id[0] == '#')
{
cfgfile.ignore(numeric_limits<streamsize>::max(), '\n'); // skip comments
continue;
}
if (eq != "=") throw runtime_error("Syntax error in the parser. Each line should follow :\n'unique parameter name' = 'value'\nA commented line begins with a '#' symbol.\n\n");
options[id] = val;
}
istringstream theStream;
string string_temp;
theStream.clear();
theStream.str(options["INITIAL_INPUT"]);
theStream >> string_temp;
strcpy(INITIAL_INPUT, string_temp.c_str());
theStream.clear();
theStream.str(options["FINAL_OUTPUT"]);
theStream >> string_temp;
strcpy(FINAL_OUTPUT, string_temp.c_str());
theStream.clear();
theStream.str(options["NB_IONS"]);
theStream >> NB_IONS;
theStream.clear();
theStream.str(options["VERBOSE"]);
theStream >> VERBOSE;
theStream.clear();
theStream.str(options["TIME_MAX"]);
theStream >> TIME_MAX;
theStream.clear();
theStream.str(options["DT_OBS"]);
theStream >> DT_OBS;
if(VERBOSE >= 1)
{
cout << "The parser has read the following configuration :\n";
typedef map<string, string>::iterator it_type;
for(it_type iterator = options.begin(); iterator != options.end(); iterator++)
{
cout << "\t" << iterator->first << " = " << iterator->second << "\n";
}
}
}
// private constructor
SINS_inputManager::SINS_inputManager()
{
}
// private destructor
SINS_inputManager::~SINS_inputManager()
{
}
And here's the error :
/data/pieges/fabian/SINS/code/src/SINS_inputManager.cu(8): error: no operator ">>" matches these operands
operand types are: std::ifstream >> std::string
/data/pieges/fabian/SINS/code/src/SINS_inputManager.cu(12): error: incomplete type is not allowed
/data/pieges/fabian/SINS/code/src/SINS_inputManager.cu(12): error: identifier "numeric_limits" is undefined
/data/pieges/fabian/SINS/code/src/SINS_inputManager.cu(12): error: type name is not allowed
/data/pieges/fabian/SINS/code/src/SINS_inputManager.cu(12): error: no instance of overloaded function "max" matches the argument list
/data/pieges/fabian/SINS/code/src/SINS_inputManager.cu(16): error: identifier "runtime_error" is undefined
/data/pieges/fabian/SINS/code/src/SINS_inputManager.cu(21): error: incomplete type is not allowed
7 errors detected in the compilation of "/tmp/tmpxft_000076aa_00000000-6_SINS_inputManager.cpp1.ii".
CMake Error at SINS_generated_SINS_inputManager.cu.o.cmake:256 (message):
Error generating file
/data/pieges/fabian/SINS/workdir/CMakeFiles/SINS.dir/code/src/./SINS_generated_SINS_inputManager.cu.o
make[2]: *** [CMakeFiles/SINS.dir/code/src/./SINS_generated_SINS_inputManager.cu.o] Erreur 1
make[1]: *** [CMakeFiles/SINS.dir/all] Erreur 2
make: *** [all] Erreur 2
Before changing the filename to CUDA extensions, it was working nicely. I searched google and found that it could be an issue with string or string.h include, but I tried all the combination I could without success. What am I doing wrong ?
EDIT : Here's the new output after adding the includes and using namespace std in the .cu :
Sorry, not exactly the same error (only for the string) :
/data/pieges/fabian/SINS/code/src/SINS_inputManager.cu(14): error: no operator ">>" matches these operands
operand types are: std::ifstream >> std::string
/data/pieges/fabian/SINS/code/src/SINS_inputManager.cu(18): error: incomplete type is not allowed
/data/pieges/fabian/SINS/code/src/SINS_inputManager.cu(18): error: identifier "numeric_limits" is undefined
/data/pieges/fabian/SINS/code/src/SINS_inputManager.cu(18): error: type name is not allowed
/data/pieges/fabian/SINS/code/src/SINS_inputManager.cu(18): error: no instance of overloaded function "max" matches the argument list
/data/pieges/fabian/SINS/code/src/SINS_inputManager.cu(22): error: identifier "runtime_error" is undefined
/data/pieges/fabian/SINS/code/src/SINS_inputManager.cu(27): error: incomplete type is not allowed
7 errors detected in the compilation of "/tmp/tmpxft_000077e5_00000000-6_SINS_inputManager.cpp1.ii".
CMake Error at SINS_generated_SINS_inputManager.cu.o.cmake:256 (message):
Error generating file
/data/pieges/fabian/SINS/workdir/CMakeFiles/SINS.dir/code/src/./SINS_generated_SINS_inputManager.cu.o
make[2]: *** [CMakeFiles/SINS.dir/code/src/./SINS_generated_SINS_inputManager.cu.o]
Erreur 1
make[1]: * [CMakeFiles/SINS.dir/all] Erreur 2
make: * [all] Erreur 2
Add next headers to .cu file:
#include <fstream>
#include <limits>
#include <stdexcept>
try to move these lines from .cuh into the .cu file
#include <map>
#include <string>
#include <iostream>
using namespace std;
especially this line using namespace std;.
I have a class called Video and is defined as the following:
class Video
{
public:
Video() { }
~Video()
{
}
unsigned int m_max_ad_duration;
unsigned int m_max_skippable_duration;
unsigned int m_start_delay;
unsigned short int m_inventory_type;
unsigned short int m_skippable_Request;
};
If i have the above in a fresh file called Video.h the build works fine, however when i declare the above in an existing file containing a number of classes the build fails with errors such as
../../include/CampaignCache.h:33:56: error: ‘Video’ was not declared in this scope
../../include/CampaignCache.h:33:62: error: template argument 1 is invalid
../../include/CampaignCache.h:33:62: error: template argument 2 is invalid
../../include/CampaignCache.h:33:64: error: template argument 2 is invalid
../../include/CampaignCache.h:33:64: error: template argument 5 is invalid
../../include/CampaignCache.h:33:89: error: invalid type in declaration before ‘;’ token
../../include/CampaignCache.h:97:51: error: ‘Video’ has not been declared
make[2]: *** [BaseOpenRTBBidRequest.o] Error 1
make[2]: Leaving directory `/home/asif/RTB3.0trunk/trunk/3.0/src/bidder/ssp/OpenRTB'
make[1]: *** [OpenRTB] Error 2
make[1]: Leaving directory `/home/asif/RTB3.0trunk/trunk/3.0/src/bidder'
make: *** [compile] Error 2
Ideally i would like the Video class within the file with subclasses, can someone please explain why one causes a build error and the other doesn't?
I just simply put the video class in an independent file and all started to work fine