user3210923
user3210923

Reputation: 13

Solution to Multiple definition in C++

guys, this is my first question in StackOverflow so forgive me if make any mistake.
I am writing a small project which contains 2 source files and 3 header files.

// some_template_functions.h

#ifndef SOME_TEMPLATE_FUNCTION_H
#define SOME_TEMPLATE_FUNCTION_H

template <typename T>
int getvalue(string line, string key, T & val)
{
    // method to get value (all the types except string) from line using key
}
template <>
int getvalue<string>(string line, string key, string &val)
{
    // method to get some string from line using key, similar to getvale<int>
    // but with slight difference to handle some special characters
}

#endif

//myclass.h

#ifndef MYCLASS_H
#define MYCLASS_H
#include "some_template_functions.h"

class MYCLASS
{
    //declarations of constructors, member functions and members
    double member_double;
    string member_string;
}

#endif

//myclass.cpp

#include "myclass.h"

MYCLASS:MYCLASS()
{
    // for each member
    // using "getvalue" defined in "SOME_TEMPLATE_FUNCTION.H" to get the values 
    getvalue(line, key, member_double);
    getvalue(line, key, member_string);
}

//main.cpp

#include "myclass.h"
#include "some_template_functions.h"

int main()
{
    myclass A;
    int some_value;
    getvalue(line, key, value);
    return 0;
}

I have no problem compiling the main.o and myclass.o but it is just when I was trying to link the two object files I got error message like:

     myclass.cpp: multiple definition of int getvalue<std::basic_string><char, std::char_traits<char>, ...> and etc.    
     /tmp/cc22zEow.o:main.cpp: first defined here    
     collect2: ld returned 1 exit status    

I know the reason probably is because I am including "some_template_function.h" in both myclass.h and main.cpp, each myclass.o and main.o is going to have its own definition of getvalue which is causing the problem. If I change

#include "some_template_functions.h"

to

#ifndef SOME_TEMPLATE_FUNCTIONS_H
#define SOME_TEMPLATE_FUNCTIONS_H
#endif

the constructors of MYCLASS is not goint to work.

I plan to expand the "some_template_functions.h" and its .cpp file in the future so if possible I would like to keep them separated from the other files. And because the way I am declaring function "getvalue" my attempt to move its definition to .cpp file was not working out for me very well.

I've tried to solve this problem for days but since I just start to learn C++ so far I could not get this right. So please, any suggestions will be appreciated! Thanks in advance!

Upvotes: 1

Views: 172

Answers (1)

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153820

The specialization of getvalue<std::string>(...) isn't a template and, thus, not implicitly inline. If you want to define this function in a header, e.g., because it is close to trivial and should be inlined, you'll need to mark it explicitly as inline. If the function does anything non-trivial it may be worth merely declaring the specialization in the header and defining it in a suitable translation unit.

Upvotes: 2

Related Questions