declaration of static function outside of class is not definition - c++

I am getting this error when I compile with GCC:
error: declaration of 'static int utils::StringUtils::SplitString(const std::string&, const std::string&, std::vector<std::basic_string<char> >&, bool)' outside of class is not definition
Code:
Header:
namespace utils
{
/*
* This class provides static String utilities based on STL library.
*/
class StringUtils
{
public:
/**
* Splits the string based on the given delimiter.
* Reference: http://www.codeproject.com/Articles/1114/STL-Split-String
*/
static int SplitString( const std::string& input,
const std::string& delimiter,
std::vector<std::string>& results,
bool includeEmpties = true );
};
};
Source:
namespace utils
{
int StringUtils::SplitString( const std::string& input,
const std::string& delimiter,
std::vector<std::string>& results,
bool includeEmpties );
{
....
}
}

Take the semi-colon off the end of the definition in your source file! Copy-paste error =)

I believe you need to lose that semicolon in your source file. Should be:
namespace utils
{
int StringUtils::SplitString( const std::string& input,
const std::string& delimiter,
std::vector<std::string>& results,
bool includeEmpties ) // <--- No more semi-colon!
{
....
}
}

Related

C++ compile error: redefinition of 'class::class'

I have added the errors within comment lines of the code for the highlighted lines by the compiler.
header file:
#ifndef ADDRESS_H_EXISTS
#define ADDRESS_H_EXISTS
#include <iostream>
#include <string>
using namespace std;
class Address{
private:
string address1;
string address2;
string city;
string state;
string zipCode;
public:
Address(){} //note: 'Address::Address()' previously defined here|
Address(
const string &address1,
const string &address2,
const string &city,
const string &state,
const string &zipCode
){}
NOTE: #endif exists at the end of header file
source file:
#include <iostream>
#include <string>
#include "address.h"
using namespace std;
Address::Address(){} // error: redefinition of 'Address::Address()'
Address::Address( // error: redefinition of 'Address::Address(const string&,
// const string&, const string&, const string&, const string&)'|
const string &address1,
const string &address2,
const string &city,
const string &state,
const string &zipCode
):
address1(address1),
address2(address2),
city(city),
state(state),
zipCode(zipCode)
{
Address::address1 = address1_c;
Address::address2 = address2_c;
Address::city = city_c;
Address::state = state_c;
Address::zipCode = zip_c;
}
All of the most popular questions about this error concluded that header guards were needed, although, there are guards already included in this code.
I thought I was misunderstanding how to properly separate the initialization list between header and source files but when I commented that out it was still producing the same error.
What you're typically supposed to do is define the function prototypes in the header file, and the function definition in the source file. However, in your header file, you seem to have specified a definition of the function already using the empty {} brackets. Hence the compiler is complaining that you've redefined the function definition in the source file. If you remove those two {} empty blocks in the header file and replace them with a semicolon ;, it should solve this error.
Basically, it should look like this in your header:
Address();
Address(
const string &address1,
const string &address2,
const string &city,
const string &state,
const string &zipCode
);
You are getting redefinition errors ( which i think are linker errors, and not compile errors ) because Address::Address() and Address::Address(const string&, const string&, const string&, const string&, const string&) are already defined in the header file, and you define them again in the CPP file
To avoid that, you need to replace function definition by declarations in your header file, by replacing {} by ; in your header file, this way :
public:
Address(); //By replacing '{}' by ';', you change that function definition into a function DECLARATION
Address(
const string &address1,
const string &address2,
const string &city,
const string &state,
const string &zipCode
); // Same for here
At the exception of inline and template functions, function declaration goes in header file, and definitions goes into the CPP file

Template file not working correctly in CodeLite?

Every time I create a new project in my workplace I run into the problem with templates. For example, I'll create a new class, which CodeLite will create a .h file and a .cpp file for me, and then I'll change that .cpp file into a .template by renaming the file. It sometimes works, and sometimes doesn't. Sometimes I have to clean my workplace for it to work, other times I need to exit out of CodeLite and reopen it. This time these solutions are not working for me, but maybe I am missing something. Here's my code:
.h file
#ifndef TABLE1_H
#define TABLE1_H
#include <cstdlib> // Provides size_t
namespace main_savitch_12A
{
template <class RecordType>
class table
{
public:
// MEMBER CONSTANT -- See Appendix E if this fails to compile.
static const std::size_t CAPACITY = 811;
// CONSTRUCTOR
table( );
// MODIFICATION MEMBER FUNCTIONS
void insert(const RecordType& entry);
void remove(int key);
// CONSTANT MEMBER FUNCTIONS
bool is_present(int key) const;
void find(int key, bool& found, RecordType& result) const;
std::size_t size( ) const { return used; }
private:
// MEMBER CONSTANTS -- These are used in the key field of special records.
static const int NEVER_USED = -1;
static const int PREVIOUSLY_USED = -2;
// MEMBER VARIABLES
RecordType data[CAPACITY];
std::size_t used;
// HELPER FUNCTIONS
std::size_t hash(int key) const;
std::size_t next_index(std::size_t index) const;
void find_index(int key, bool& found, std::size_t& index) const;
bool never_used(std::size_t index) const;
bool is_vacant(std::size_t index) const;
};
}
#include "table1.template" // Include the implementation.
#endif
.template file
template<class RecordType>
table<RecordType>::table(){
used = 32;
}
main file
#include <stdio.h>
#include "table1.h"
int main(int argc, char **argv)
{
printf("hello world\n");
return 0;
}
My template and my .h files are called table1. The error I am getting when I run the program is in the template file. It reads: "table does not name a type" How can I fix this issue?
In your template implementation your are missing the namespace, use this:
template <class RecordType>
main_savitch_12A::table<RecordType>::table()
{
used = 32;
};

netbeans multiple definition; first defined in _nomain.o error on building C++ simple test

I've created three C++ simple tests in tests folder in my projects directory. When I created the first C++ simple test and built it there was no problem but when I create the second or third, innumerable errors listed below are generated
build/DebugDynamic/GNU-Linux-x86/ClientSocket.o: In function `Socket::is_valid() const':
/home/gowtham/workspace/base/ClientSocket.cpp:8: multiple definition of `ClientSocket::ClientSocket(std::string, int, Socket::SOCKET_TYPE, std::string, std::string, std::string)'
build/DebugDynamic/GNU-Linux-x86/ClientSocket_nomain.o:/home/gowtham/workspace/base/ClientSocket.cpp:8: first defined here
The linker command is
g++ -g -O0 -o build/DebugDynamic/GNU-Linux-x86/tests/TestFiles/f3 build/DebugDynamic/GNU-Linux-x86/tests/tests/sizeInfo.o build/DebugDynamic/GNU-Linux-x86/ClientSocket_nomain.o build/DebugDynamic/GNU-Linux-x86/FFJSON_nomain.o build/DebugDynamic/GNU-Linux-x86/JPEGImage_nomain.o build/DebugDynamic/GNU-Linux-x86/ServerSocket_nomain.o build/DebugDynamic/GNU-Linux-x86/Socket_nomain.o build/DebugDynamic/GNU-Linux-x86/logger_nomain.o build/DebugDynamic/GNU-Linux-x86/myconverters_nomain.o build/DebugDynamic/GNU-Linux-x86/mycurl_nomain.o build/DebugDynamic/GNU-Linux-x86/mystdlib_nomain.o build/DebugDynamic/GNU-Linux-x86/myxml_nomain.o build/DebugDynamic/GNU-Linux-x86/ClientSocket.o build/DebugDynamic/GNU-Linux-x86/FFJSON.o build/DebugDynamic/GNU-Linux-x86/JPEGImage.o build/DebugDynamic/GNU-Linux-x86/ServerSocket.o build/DebugDynamic/GNU-Linux-x86/Socket.o build/DebugDynamic/GNU-Linux-x86/logger.o build/DebugDynamic/GNU-Linux-x86/myconverters.o build/DebugDynamic/GNU-Linux-x86/mycurl.o build/DebugDynamic/GNU-Linux-x86/mystdlib.o build/DebugDynamic/GNU-Linux-x86/myxml.o -lxml2 -lpthread -lssl -lcrypto -lz
netbeans is including a duplicate object file _nomain.o for every object file in the project.
ClientSocket.h
#ifndef CLIENTSOCKET_H
#define CLIENTSOCKET_H
#include "Socket.h"
class ClientSocket : public Socket {
public:
class AftermathObj {
public:
void* (*aftermath)(void* aftermathDS, bool isSuccess);
void* aftermathDS;
std::string payload;
std::string* payloadPTR;
std::string error;
int __flags;
pthread_t t;
ClientSocket* cs;
AftermathObj() {
};
~AftermathObj() {
};
};
ClientSocket();
ClientSocket(std::string host, int port, Socket::SOCKET_TYPE socketType = Socket::DEFAULT, std::string trustedCA = "", std::string privatecert = "", std::string privatekey = "");
std::string host;
int port;
void reconnect();
void disconnect();
bool send(const std::string s, int __flags) const;
bool send(const std::string* s, int __flags) const;
bool send(const std::string s) const;
virtual ~ClientSocket();
const ClientSocket& operator <<(const std::string&) const;
void asyncsend(std::string payload, AftermathObj* after_math_obj);
void asyncsend(std::string* payload, AftermathObj* aftermath_obj);
const ClientSocket& operator >>(std::string&) const;
private:
//Socket* soc;
static void* socsend(void*);
struct soc_send_t_args {
std::string s;
void* (&aftermath)(void* aftermathDS);
void* aftermathDS;
};
pthread_key_t socket_thread_key;
};
#endif

Error: variable '*' has initializer but incomplete type and one other

I know there are a couple other questions on this specific question, but nothing that I can find on it seems to work, so I'm posting my specific code.
Here is the code:
#ifndef __MEMORY_TRACKER_H__
#define __MEMORY_TRACKER_H__
#include <unordered_map>
namespace cige
{
namespace memory
{
class CIGE_API MemoryTracker
{
protected:
typedef struct AllocRecord
{
size_t bytes;
std::string filename;
size_t line;
std::string func;
AllocRecord() :
bytes(0), line(0)
{ }
AllocRecord(size_t sz, const char* file, size_t ln, const char* fun) :
bytes(sz), line(ln)
{
if (file)
filename = file;
if (fun)
func = fun;
}
} AllocRecord;
std::string m_leakFileName;
bool m_dumpToConsole;
typedef std::unordered_map<void*, AllocRecord> AllocMap;
AllocMap m_allocationMap;
size_t m_totalAllocations;
bool m_recordEnable;
protected:
void reportLeaks();
MemoryTracker() :
m_leakFileName("CIGEMemory.log"), m_dumpToConsole(true), m_totalAllocations(0), m_recordEnable(true)
{ }
public:
void setReportFileName(const std::string& name)
{
m_leakFileName = name;
}
const std::string& getReportFileName() const
{
return m_leakFileName;
}
void setReportToConsoleOutput(bool b)
{
m_dumpToConsole = b;
}
bool getReportToConsoleOutput() const
{
return m_dumpToConsole;
}
void setRecordEnable(bool b)
{
m_recordEnable = b;
}
bool getRecordEnable() const
{
return m_recordEnable;
}
size_t getTotalMemoryAllocated() const
{
return m_totalAllocations;
}
void _recordAlloc(void* ptr, size_t sz, const char* file = nullptr, size_t ln = 0, const char* fun = nullptr);
void _recordDealloc(void* ptr);
~MemoryTracker()
{
reportLeaks();
}
static MemoryTracker& get();
};
}
}
#endif // __MEMORY_TRACKER_H__
I'm getting: variable 'cige::memory::CIGE_API cige::memory::MemoryTracker' has initializer but incomplete type at the line with the class declaration. I've looked all over and I cant find any answers that have fixed this issue.
I'm also having the error expected '}' or ',' or ';' before 'protected' at the line with protected, right above the struct.
Any help with either of these two errors would be appreciated.
EDIT: CIGE_API is defined in a separate file (which is included), as __declspec(dllexport).
EDIT2: I fixed my problem (see the answer below). It was basically just Code::Blocks derping out pretty bad.
Looks like CIGE_API is not defined. So compiler try to resolve it like variable declaration class Type Variable {initializer-list}, where Type is CIGE_API and Variable is MemoryTracker.
In other words, syntactically you're predeclaring CIGE_API type and creating variable of this type instead of defining a class.
The definition
class CIGE_API MemoryTracker { ... };
is not valid C++. I guess CIGE_API is a macro defined to an implementation specific extension, but you didn't include the corresponding header which defines that macro.
Ok I ended up fixing my own problem. Code::Blocks wasn't properly finding files that were in my project (about the third time this has happened).
In entirely unrelated news, does anyone know another cross-platform IDE that works well for C++? (I already know about Eclipse).

Win32 program compiler errors in class definition file

I am trying to Compile in Visual C++ and just added this config file loader/parser to my project. For some ever function defined in class CProfileData is receiving at least one of two errors:
missing type specifier - int assumed.
syntax error : missing ',' before '&'
When obviously this should just be a referenced string
#ifdef UVSS_EXPORTS
#define UVSS_API __declspec(dllexport)
#else
#define UVSS_API __declspec(dllimport)
#endif
class CProfileData
{
public:
UVSS_API CProfileData(){};
UVSS_API CProfileData(const string& profileFile);
UVSS_API ~CProfileData(void);
UVSS_API bool GetVariable( const string& sectionName, const string& variableName, string& valueRet );
UVSS_API bool GetSection( const string& sectionName, SECTION_MAP **pMapRet );
UVSS_API bool GetVariableW( const string& sectionName, const string& variableName, wstring& valueRet );
UVSS_API bool GetVariableInt( const string& sectionName, const string& variableName, int *pIntRet );
private:
void ToLower( string& str );
void TrimWhitespace( string& str);
bool IsComment( const string& str );
bool IsSection( const string& str, string& secName );
bool IsVariable( const string& str, string& name, string& value );
PROFILE_MAP m_mapProfile;
};
Include <string>:
#include <string>
And write std::string wherever you've written string.
Its not a good idea to do either of the following in a header file:
using namespace std; //avoid doing this
using std::string; //avoid doing this as well
Ensure that these two lines appear before including this header:
#include <string>
using std::string;