0

テンプレートクラスを作成するこのプリプロセッサ依存の方法を発見したとき、私はちょうどいじっていました:

#include <iostream>
#include <typeinfo>

// Is this a valid template class?
#define TEMPLATE_CLASS(T)\
class TemplateClass_ ## T\
{\
private:\
    T value;\
public:\
    void print_type()\
    {\
        std::cout << typeid(T).name() << std::endl;\
    }\
}

class Sample {};

TEMPLATE_CLASS(int) obj1;
TEMPLATE_CLASS(char) obj2;
TEMPLATE_CLASS(Sample) obj3;

int main(int argc, char* argv[])
{
    obj1.print_type();
    obj2.print_type();
    obj3.print_type();
}

これを次のように簡単にコンパイルしました。

g++ src.cpp -o main.exe

出力:

i
c
6Sample

ご覧のとおり、テンプレート クラスとほとんど同じように機能します。オブジェクトはグローバルにしか宣言できないという明らかな事実を除いて、実際には を使用するときに新しいクラスをインラインで定義し、新しいクラスTEMPLATE_CLASS(T)を関数内で定義することはできません。これに対する解決策は次のとおりです。

TEMPLATE_CLASS(float);

int main() { TemplateClass_float obj; }

とにかく色々と考えさせられました。まず、これを有効なジェネリック クラスと呼ぶことはできますか? では、標準のテンプレート機能の代わりに使用できる可能性はありますか? 明らかに、標準のテンプレート機能を使用する方がはるかに便利ですが、私が言いたいのは、これでも同じように機能するかということです。最後に、C++ 標準によって定義されたテンプレート機能は、プリプロセッサで行っていることと同様のことを内部的に行いますか? そうでない場合、この実装と C++ の標準テンプレート機能の違いは何ですか?

4

4 に答える 4

7

最も単純な場合にのみ、テンプレートと同じことを行います。マクロでこれを試してください:

template <class Ty> class C {};
template <class Ty> class C<Ty*> {};
template <class Ty> class C<std::vector<Ty> > {};
于 2012-08-14T11:52:02.753 に答える
3

プリプロセッサを使用してマクロを作成できます。C を使用している場合は、これを使用して、行ったことを正確に行うことができます。C++ は言語の一部としてテンプレートを提供するため、これを行うことができます。たとえば、マクロは厳密に型指定されておらず、プリプロセッサが決して検出しないバグを検出する可能性のある多くのコンパイル時間チェックを逃すことになります。

ほぼすべての状況で、テンプレートではなくマクロを使用することは適切ではありません。あなたのコードは維持するのも難しく、従う必要があります。別の言い方をすれば、同僚にあなたのことをあまり考えてほしくない場合や、あなたの名前が言及されることに腹を立てたい場合は、すぐにマクロを使用してください。:)

于 2012-08-14T11:55:28.290 に答える
3

あなたがやっていることはtemplatesではなくmacrosです。テンプレートの代わりにマクロを使用することは、自分自身を撃つ良い方法です。ここからの例ですmsdn

//macro
#define min(i, j) (((i) < (j)) ? (i) : (j))

//template
template<class T> T min (T i, T j) { return ((i < j) ? i : j) }

マクロには次のような問題があります。

  1. マクロ パラメーターが互換性のある型であることをコンパイラが確認する方法はありません。マクロは、特別な型チェックなしで展開されます。

  2. i および j パラメータは 2 回評価されます。たとえば、いずれかのパラメーターにポストインクリメント変数がある場合、インクリメントは 2 回実行されます。

  3. マクロはプリプロセッサによって展開されるため、コンパイラ エラー メッセージは、マクロ定義自体ではなく、展開されたマクロを参照します。また、マクロはデバッグ中に展開された形式で表示されます。

于 2012-08-14T11:50:31.680 に答える
1

クラスの実際の型を難読化するため、関数などの操作が難しくなります。また、マクロが使用されるたびに新しいクラスを定義するため、アプローチではテンプレートの再帰を使用できないようです。その上、テンプレートクラスの例外ケースを定義できないため、チューリング完全にすることはできません。また、値ベースのテンプレート クラスを定義する機能も欠いています:DI は、もっと多くの問題を簡単に挙げることができると思いますが、これらは主要なものかもしれません。

于 2012-08-14T11:51:28.193 に答える