0

私はこのようなコードを見てきました:

#include <iostream>

// member_function_templates.cpp
struct X
{
   template <class T> void mf(T* t) {
     std::cout << "in mf t is: " << *t << std::endl;
   }
};

int main()
{
   int i = 5;
   X* x = new X();
   x->mf(&i); //why can this be called without specifying a type as in: x->mf<int>(&i) ??
}

私の質問は、メインのコメントにあります。なぜあなたは呼ぶことができます:

x->mf(&i);

...タイプを指定せずに?直感はそれが次のように呼ばれるべきであると言います:

x->mf<int>(&i);

...しかし、どうやらこのように呼び出す必要はないようです(上記は、テンプレートを明示的に指定せずに、どちらの方法でもgcc 4.7でコンパイルします)。

また、テンプレートの型を指定せずに呼び出すと、(テンプレート関数定義の)Tの型はどうなりますか?(デフォルトでは、引数として関数mfに渡すもののタイプになっていると思いますが、これがどのように機能するかについてさらに説明するとよいでしょう)

4

1 に答える 1

3

これはテンプレートタイプの推定であり、テンプレート化されていないクラスのメンバーだけでなく、すべてのテンプレート関数に適用されます。T基本的に、コンパイラーは、関数への引数から型が何を意味するかを(標準の一連の規則に従って)推測することができます。コンパイラがへの呼び出しを見ると、それがであるmf(&i);ことがわかります。したがって、引数はであり、(*)を持つオーバーロードが必要であることを意味します。iintint*T==int

テンプレートの特定の特殊化を強制する場合でも、特定のテンプレート引数のセットを提供できます。たとえば、テンプレートへのパラメータを推定されたものではなく、それから変換可能なものにしたい場合は、次のようにします。

template<typename T>
void foo(T arg) {...}

int i = 10;
foo(i);             // calls foo<int>(i)
foo<double>(i);     // calls foo<double>(static_cast<double>(i))

(*)引数が有効になる可能性のある複数のタイプが存在する可能性があるため、これよりも少し複雑Tですが、言語のルールによって、どの特定のものT推測されるかが決まります。この場合はですint

于 2013-02-14T19:16:50.217 に答える