3

すべてのコード私が読んだことから、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.

PSスタックオーバーフローでこの質問のバリエーションを見たことがありますが、この正確な質問ではありません。

4

2 に答える 2

8

はい、意味はありますが、テンプレートと組み合わせてもあまり効果がありません。

キーワードの主な効果は、inlineこの関数が複数のコンパイル単位で同じ定義で表示される可能性があることをコンパイラーに伝えることです。そのため、リンカーに対して「select-one」としてフラグを立てる必要があります (複数の定義エラーが発生しないようにするため)。 )。テンプレートにはすでにこの機能があります。

inlineまた、関数をインライン化する必要があると考えるコンパイラーへのヒントですが、コンパイラーは通常、インライン化の最適化に関する最終決定を独自に行います。

于 2012-04-23T14:07:35.060 に答える
0

関数がヘッダーファイルで定義されている場合、インラインキーワードは意味がありますか?

です。次のプロジェクトでは、インライン キーワードが省略されているため、msvc と g++ の両方でリンカー エラーが発生します。


main.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

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

さて、なぜこれが起こると思いますか?コンパイラは、コンパイル時にヘッダー ファイルの内容を *.cpp ファイルに挿入するためです。関数は「インライン」ではないため、その名前はリンカに認識され、各.obj/ .o ファイルは と の独自のコピーを取得しA::f()ますa()。リンカーは、どちらを使用する必要があるかを認識せず、文句を言います。関数をインラインにすると、すべて正常に動作します。

ただし、テンプレートは別の話です。

于 2012-04-23T14:32:35.507 に答える