9

私はこのコードに出くわしました(何かが足りない場合に備えて、すべての詳細を含めようとしています):

template< typename TYPE = TYPE_with_an_arbitrarily_long_name,
          typename KIND = KIND_with_an_arbitrarily_long_name>

class Foo
{
public:
    virtual void bar(TYPE& t, KIND& k) = 0;
};

そして、私が理解していない部分は、テンプレート内の割り当てです。

template <typename TYPE = TYPE_with_an_arbitrarily_long_name, ..

私はこれの効果を理解しようとしてきましたが、今のところ何も生み出すことができませんでした。これが私が試したものです:

#include <iostream>
#include <typeinfo>
using namespace std;

template<typename T>
void foo(T t) {
    cout << typeid(t).name() << " ";
}

template<typename T = int>
void bar(T t) {
    cout << typeid(t).name() << " ";
}

template<typename T = double>
void baz(T t) {
    cout << typeid(t).name() << " ";
}

int main()
{
    cout << "\nfoo: ";
    foo(3); foo<int>(3); foo<double>(3);
    cout << "\nbar: ";
    bar(3); bar<int>(3); bar<double>(3);
    cout << "\nbaz: ";
    baz(3); baz<int>(3); baz<double>(3);
    return 0;
}

プリントアウト:

foo: i i d
bar: i i d
baz: i i d

だから私の質問は:

  1. 内部での割り当ての効果は何templateですか?
  2. 上記の例で使用する目的は何ですか?
  3. 3番目の質問はありません。

どんな助けでも大歓迎です。

EDITで判明した関数はc++11でのみコンパイル可能です

4

6 に答える 6

8

これは「デフォルトのテンプレート引数」と呼ばれ、デフォルトの関数パラメータと同様に、何も指定されていない場合に使用されるタイプを指定します。この手法はクラスで広く使用されています。std::vectorまたはの定義をstd::string見ると、複数のデフォルトの型パラメーターがあることがわかります。

関数テンプレートのデフォルトの型パラメーターの最適な使用法は、型引数が実際の引数から簡単に推測できず、明示的に指定されていない場合です。コンパイラーはデフォルトの引数を使用します。この例では、実際の呼び出しパラメーターから簡単に推測できるため、デフォルトのタイプは必要ありません。

C ++ 0xのデフォルトの型パラメーターは、クラステンプレートでのみ許可されるまで、関数テンプレートで使用することはできませんでした。C ++ 0xでは変更されましたが、一部の古いコンパイラ(Visual C ++ 2008など)では使用できませんでした。

于 2012-11-26T14:00:36.573 に答える
7

これらは割り当てではなく、関数のデフォルト値引数に同様の構文があるのと同様に、テンプレートの型引数の「デフォルト値」です。これらは、明示的な引数が指定されていない場合に使用されます。

bar例のbaz関数テンプレートの場合、これらの関数の場合、指定された引数から派生するため、意味がありませんT

于 2012-11-26T13:58:58.787 に答える
6

関数テンプレートは、デフォルトのテンプレート引数を示すのに最適な構成ではない場合があります。template-structsに似たものは次のとおりです。

#include <iostream>
#include <typeinfo>

template<typename T = int>
struct foo {
   static void f() {
      std::cout << typeid(T).name() << "\t";
   }
};

template<typename T = double>
struct bar {
   static void f() {
      std::cout << typeid(T).name() << "\t";
   }
};

int main() {
  foo<>::f(); foo<int>::f();  foo<double>::f();  std::cout << std::endl;
  bar<>::f(); bar<int>::f();  bar<double>::f();  std::cout << std::endl;
}

これを実行すると、次のようになります。

% ./a.out 
i   i   d   
d   i   d   
于 2012-11-26T14:00:12.773 に答える
2
  1. テンプレートパラメータリスト内の「割り当て」は、関数パラメータリストと同様にデフォルトのパラメータです。つまり、あなたの例でFoo<>は、はと同じFoo<TYPE_with_an_arbitrarily_long_name, KIND_with_an_arbitrarily_long_name>でありFoo<int>、はと同じFoo<int, KIND_with_an_arbitrarily_long_name>です。
  2. 例では使用されません。をまったく使用せずFoo、およびのパラメーターは、指定bazbarれた引数からコンパイラーによって常に推測されます。
于 2012-11-26T14:02:27.687 に答える
1

これらはデフォルトのテンプレート引数です。テンプレートのデフォルト引数を使用して、それらの使用法を単純化できます。

たとえば、2つのテンプレートパラメータがあり、最後の1つにデフォルトのタイプを指定する場合は、1つのタイプのみを指定する必要があります。

std::vectorたとえば、次のように定義されます

template < class T, class Allocator = allocator<T> > class vector;

ここに、のデフォルトのテンプレート引数がAllocatorあるので、1つの引数だけでベクトルを定義できます

std::vector<int> v;
于 2012-11-26T14:01:41.970 に答える
-3

あなたが探しているのは「テンプレートの特殊化」です

ここにいくつかの例/説明へのリンクがあります

于 2012-11-26T14:00:11.903 に答える