Reputation: 13
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
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 inline
d, 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