如果函数在头文件中定义,则内联关键字是否有意义?

时间:2012-04-23 14:04:26

标签: c++ templates inline

所有代码从我读过的内容来看,A1& A2是相同的,但如果A3与A2相同,我不会。我知道代码会编译,因为所有A类都被tmemplated。

注意:所有课程和方法声明在.h文件中。

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。我在stackoverflow上看过这个问题的变体,但不是这个问题。

2 个答案:

答案 0 :(得分:8)

是的,这很有意义,但与模板结合使用效果不大。

inline关键字的主要作用是告诉编译器该函数在多个编译单元中可能出现相同的定义,因此需要将其标记为链接器的“select-one”(所以你没有得到多个定义错误)。模板已具有此功能。

inline也是对编译器的暗示,您认为函数应该内联,但编译器通常会自行决定内联优化。

答案 1 :(得分:0)

  

如果在头文件中定义了函数,内联关键字是否有意义?

是的。以下项目将在msvc和g ++上产生链接器错误,因为省略了内联关键字:


<强>的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文件(适用于Qt 4构建系统):​​

TEMPLATE = app
TARGET = 
DEPENDPATH += .
INCLUDEPATH += .

HEADERS += a.h
SOURCES += b.cpp main.cpp

编译输出

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

克++:


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

现在,你觉得为什么会这样?因为编译时编译器头文件的内容插入到* .cpp文件中。由于函数不是“内联”,因此链接器会知道其名称,并且每个 .obj / .o文件将获得其A::f()和{{1}的唯一副本}。链接器不知道你应该使用哪个并且会抱怨。如果你使函数内联,一切都会正常工作。

然而,模板是另一个故事。