3

所有代码根据我的阅读,A1 和 A2 是相同的,但如果 A3 与 A2 相同,我不会。我知道代码会编译,因为所有的 A 类都是 tmemplate。

注意:所有的类和方法声明都在一个 .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.

PS我在stackoverflow上看到了这个问题的变体,但不是这个确切的问题。

4

2 回答 2

8

是的,它是有意义的,但是与模板结合起来并没有太大的效果。

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

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

于 2012-04-23T14:07:35.060 回答
0

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

这是。由于省略了 inline 关键字,以下项目将在 msvc 和 g++ 上产生链接器错误:


主.cpp

#include "a.h"

int main(int argc, char** argv){
    A obj;
    obj.f();
    a();
    b();
    return 0;
}

#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()and副本a()。Linker 不会知道你应该使用哪个并且会抱怨。如果你使函数内联,一切都会正常工作。

但是,模板是另一回事。

于 2012-04-23T14:32:35.507 回答