1
votes

I'm developing a C++ solution with Visual Studio 2015.

I have a cpp source file and header file hpp with this declaration.

Header:

#ifndef MyLib__FREEFUNCTIONS__INCLUDE__
#define MyLib__FREEFUNCTIONS__INCLUDE__

#include <iostream>
#include <vector>
#include <string>
#include <sstream>

using namespace std;

// Check if 'str' is null, empty or consists only of white-space characters. 
inline bool IsNullOrWhiteSpace(string str);

// More functions
[ ... ]

#endif

And Source code:

#include "FreeFunctions.h"

inline bool IsNullOrWhiteSpace(string str)
{
    return (str.empty() || (str.find_first_not_of(' ') == string::npos));
}

I use this function in a class:

#include "ConvertToOwnFormat.h"
#include "FreeFunctions.h"

ConvertToOwnFormat::ConvertToOwnFormat()
{
}


ConvertToOwnFormat::~ConvertToOwnFormat()
{
}

vector<Entry> ConvertToOwnFormat::ReadCatalogue(string path)
{
    if (!IsNullOrWhiteSpace(path)
    {
        [ ... ]
    }
}

And I get the following error in ConvertToOwnFormat::ReadCatalogue:

Error LNK2019 external symbol "bool __cdecl IsNullOrWhiteSpace(class std::basic_string,class std::allocator >)" (?IsNullOrWhiteSpace@@YA_NV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) unresolved referenced by the function "public: class std::vector > __cdecl ConvertToOwnFormat::ReadCatalogue(class std::basic_string,class std::allocator >)" (?ReadCatalogue@ConvertToOwnFormat@@QEAA?AV?$vector@VEntry@@V?$allocator@VEntry@@@std@@@std@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@3@@Z) MyProjectLib D:\Fuentes\Repos\MyProject\MyProjectLibConsoleTest\ConsoleMyProjectLib\Lib.lib(ConvertToOwnFormat.obj) 1

1
I may be wrong, but inline I believe is usually for declaration of methods within the header, rather than the cpp file. Have you tried this?D Hansen
Yes, I have tried and it links. Thanks.VansFannel
This isn't the problem, but names that contain two consecutive underscores (MyLib__FREEFUNCTIONS__INCLUDE__) and names that begin with an underscore followed by a capital letter are reserved to the implementation. Don't use them.Pete Becker
This isn't also the problem, but using namespace inside a header is discouraged (stackoverflow.com/questions/5849457/…)Garf365
Thanks a lot for your comments. I'm learning and they are much appreciated.VansFannel

1 Answers

5
votes

You have to put declaration of methods within the header. inline tells to compiler that it should replace call of function with the core of function. So, it need it at compilation time for every unit of compilation which use it

#ifndef MyLib__FREEFUNCTIONS__INCLUDE__
#define MyLib__FREEFUNCTIONS__INCLUDE__

#include <iostream>
#include <vector>
#include <string>
#include <sstream>

// Check if 'str' is null, empty or consists only of white-space characters. 
inline bool IsNullOrWhiteSpace(std::string str)
{
    return (str.empty() || (str.find_first_not_of(' ') == std::string::npos));
}

// Others functions, prototype, ...

#endif

or remove inline in both source and header files


It's totally out of topic but never put a using namespace inside a header: a header should offer something but should not impose something like namespace. See also "using namespace" in c++ headers