7

私はC++Templates Complete Guideを読んでいて、この非型関数テンプレートパラメーターコードに出くわしました(関数定義と呼び出しを除くmain()と他の部分を追加しました):

#include <vector>
#include <algorithm>
#include <iostream>

template <typename T, int value>
T add (T const & element){
  return element + value;
}

int main() {
  int a[] = {1,2,3,4};
  int length = sizeof (a) / sizeof (*a);
  int b[length];
  std::transform (a, a + length, b, (int(*)(int const &))add <int, 5>); //why?
  std::for_each (b, b + length, [](int const & value){ std::cout << value << '\n'; });
  return 0; 
}

本を読んだ後、なぜ関数呼び出しの型キャストが必要なのか理解できませんでしたか?

編集:本からの説明:

addは関数テンプレートであり、関数テンプレートは、オーバーロードされた関数のセットに名前を付けると見なされます(セットにメンバーが1つしかない場合でも)。ただし、現在の標準によれば、オーバーロードされた関数のセットをテンプレートパラメータの推定に使用することはできません。したがって、関数テンプレート引数の正確なタイプにキャストする必要があります:...

コンパイラ:Ubuntu10.10のg++ 4.5.1

4

1 に答える 1

6

厳密に言えば、テンプレートの引数リストを指定するだけでは、関数テンプレートの特殊化を参照することはできません。常にターゲットタイプ(渡す関数パラメータータイプ、キャスト先のキャストタイプ、割り当てた変数タイプなど)が必要でした。

これは、たとえば、ターゲットタイプにテンプレートパラメータが完全に含まれていない場合でも当てはまります。

template<typename T> void f() { }
template<typename T> void g(T) { }

int main() {
  g(f<int>); // not strictly valid in C++03
  g((void(*)())f<int>); // valid in C++03
}

委員会は、C ++ 0xに採用され、C ++ 03モードで一般的なコンパイラーによって採用されたルールを追加しました。これにより、すべてのテンプレートパラメーターのタイプを提供する完全なテンプレート引数リストをすべてのテンプレートとともに提供すると、ターゲットタイプを省略できます。デフォルトのテンプレート引数。

于 2011-07-24T17:21:54.763 に答える