Reputation: 892
All code From what I've read, A1 & A2 are identical, but I don't if A3 is identical to A2. I know the code will compile since all of the A classes are tmemplated.
Note: All of the class & method declarations are in a .h file.
template <typename _Ty>
class A1 {
public:
A1();
void foo() { ... }
};
template <typename _Ty>
class A2 {
public:
A2();
void foo();
};
template <typename _Ty>
inline void A2<_Ty>::foo() { ... }
template <typename _Ty>
class A3 {
public:
A3();
void foo();
};
template <typename _Ty>
void A3<_Ty>::foo() { ... } // note: No inline keyword here.
P.S. I've seen variants of this question on stackoverflow, but not this exact question.
Upvotes: 3
Views: 1101
Reputation: 26439
Is inline keyword meaningful if function is defined in header file?
It is. Following project will produce linker error on both msvc and g++ BECAUSE of the omission of inline keyword:
main.cpp:
#include "a.h"
int main(int argc, char** argv){
A obj;
obj.f();
a();
b();
return 0;
}
a.h:
#ifndef A_HEADER
#define A_HEADER
class A{
public:
void f();
};
void a(){
}
void b();
void A::f(){
}
#endif
b.cpp:
#include "a.h"
void b(){
A obj;
obj.f();
a();
}
*.pro file (for Qt 4 build system):
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
HEADERS += a.h
SOURCES += b.cpp main.cpp
Compilation output:
cl.exe:
main.obj : error LNK2005: "void __cdecl a(void)" (?a@@YAXXZ) already defined in b.obj
main.obj : error LNK2005: "public: void __thiscall A::f(void)" (?f@A@@QAEXXZ) already defined in b.obj
debug\1234.exe : fatal error LNK1169: one or more multiply defined symbols found
g++:
debug/main.o: In function `Z1av':
D:\c++\1234/a.h:6: multiple definition of `a()'
debug/b.o:D:\c++\1234/a.h:6: first defined here
debug/main.o:D:\c++\1234/a.h:11: multiple definition of `A::f()'
debug/b.o:D:\c++\1234/a.h:11: first defined here
collect2: ld returned 1 exit status
make[1]: *** [debug/1234.exe] Error 1
make: *** [debug] Error 2
Now, why do you think this happens? Because compiler inserts contents of header file into *.cpp file when compiling. Since function isn't "inline", its name is made known to the linker, and each .obj/.o file will get its own unique copy of A::f()
and a()
. Linker won't know which you're supposed to use and will complain. If you make functions inline, everything will work fine.
However, templates are another story.
Upvotes: 0
Reputation: 283941
Yes, it's meaningful, but doesn't have much effect when combined with templates.
The major effect of the inline
keyword is to tell the compiler that this function may appear with the same definition in multiple compilation units, so it needs to be flagged as "select-one" for the linker (so you don't get multiple definition errors). Templates already have this feature.
inline
also is a hint to the compiler that you think the function should be inlined, but the compiler usually makes the final decision on inlining optimizations on its own.
Upvotes: 8