ページ 11

関数テンプレートの明示的特殊化

Posted: 2015年3月05日(木) 17:47
by sor
C++ を2ヶ月ほど前に学び始めた初心者です。
参考書の演習問題に取り組んでおり、ある問題のプログラムが適切に作成ができずコンパイルエラーが発生し困っています。
問題は以下のとおりです。

配列の全要素の最小値を求める関数テンプレートを作成せよ。
なお、最も小さい文字列を求められるようにするために、const char* 型に明示的に特殊化したものをあわせて作成すること。 (新版明解 C++ 入門編より引用)

OS: lubuntu コンパイラ: g++

作成したソースコードを以下に示します。

コード:

#include<iostream>
#include<cstring>
#define M 16

using namespace std;

template <class Type> Type minof(const Type x[], int n)
{
  Type min = x[0];

  for(int i = 1; i < n; i++)
    if(x[i] < min)
      min = x[i];

  return min;
}

template <> const char* minof<const char*>(const char p[][M], int n)
{
  int min = 0;

  for(int i = 1; i < n; i++)
    if(strcmp(p[i], p[min]) < 0)
      min = i;

  return p[min];
}

int main()
{
  const int n1 = 4;
  int n[n1];
  double d[n1];
  char s[n1][M];

  for(int i = 0; i < n1; i++){
    cout << "整数[" << i << "] : "; cin >> n[i];
  }

  for(int i = 0; i < n1; i++){
    cout << "実数[" << i << "] : "; cin >> d[i];
  }

  for(int i = 0; i < n1; i++){
    cout << "文字列[" << i << "] : "; cin >> s[i];
  }

  cout << "最小の整数  : " << minof(n,n1) << "\n";
  cout << "最小の実数  : " << minof(d,n1) << "\n";
  cout << "最小の文字列: " << minof<const char*>(s,n1) << "\n";
}
エラーメッセージは以下のとおりです。
en0905.cpp:18:25: error: template-id ‘minof<const char*>’ for ‘const char* minof(const char (*)[16], int)’ does not match any template declaration
template <> const char* minof<const char*>(const char p[][M], int n)
^
en0905.cpp: In function ‘int main()’:
en0905.cpp:50:60: error: no matching function for call to ‘minof(char [4][16], const int&)’
cout << "最小の文字列: " << minof<const char*>(s,n1) << "\n";
^
en0905.cpp:50:60: note: candidate is:
en0905.cpp:7:28: note: template<class Type> Type minof(const Type*, int)
template <class Type> Type minof(const Type x[], int n)
^
en0905.cpp:7:28: note: template argument deduction/substitution failed:
en0905.cpp:50:60: note: cannot convert ‘s’ (type ‘char [4][16]’) to type ‘const char* const*’
cout << "最小の文字列: " << minof<const char*>(s,n1) << "\n";
^

Re: 関数テンプレートの明示的特殊化

Posted: 2015年3月05日(木) 18:44
by usao

コード:

template <class Type>
Type minof( Type x[], int n)
{ ... }

template <>
const char* minof<const char*>(const char *p[], int n)
{ ... }
でいけるかな?
オフトピック
ただ,これに直接 s を渡せなくて

コード:

const char *pStrs[n1] = { s[0],s[1],s[2],s[3] };
cout << "最小の文字列: " << minof<const char*>(pStrs,n1) << "\n";
みたくしないといけない…のか?(このへん曖昧)

Re: 関数テンプレートの明示的特殊化

Posted: 2015年3月05日(木) 20:10
by sor
返信ありがとうございます。
指摘を参考にソースコードを書き換えましたが、コンパイルエラーとなりました。

ソースコードは以下のとおりです。

コード:

#include<iostream>
#include<cstring>
#define M 16

using namespace std;

template <class Type> Type minof(const Type x[], int n)
{
  Type min = x[0];

  for(int i = 1; i < n; i++)
    if(x[i] < min)
      min = x[i];

  return min;
}

template <> const char* minof<const char*>(const char *p[], int n)
{
  int min = 0;

  for(int i = 1; i < n; i++)
    if(strcmp(p[i], p[min]) < 0)
      min = i;

  return p[min];
}

int main()
{
  const int n1 = 4;
  int n[n1];
  double d[n1];
  char s[n1][M];
  const char *pStrs[n1] = { s[0], s[1], s[2], s[3]};

  for(int i = 0; i < n1; i++){
    cout << "整数[" << i << "] : "; cin >> n[i];
  }

  for(int i = 0; i < n1; i++){
    cout << "実数[" << i << "] : "; cin >> d[i];
  }

  for(int i = 0; i < n1; i++){
    cout << "文字列[" << i << "] : "; cin >> s[i];
  }

  cout << "最小の整数  : " << minof(n,n1) << "\n";
  cout << "最小の実数  : " << minof(d,n1) << "\n";
  cout << "最小の文字列: " << minof<const char*>(pStrs,n1) << "\n";
}
エラーメッセージ

en0905.cpp:18:25: error: template-id ‘minof<const char*>’ for ‘const char* minof(const char**, int)’ does not match any template declaration
template <> const char* minof<const char*>(const char *p[], int n)

Re: 関数テンプレートの明示的特殊化

Posted: 2015年3月05日(木) 20:18
by みけCAT
No: 3の18行目を

コード:

template <> const char* minof<const char*>(const char * const p[], int n)
としたらコンパイルが通りました。
参考にした過去ログ

Re: 関数テンプレートの明示的特殊化

Posted: 2015年3月05日(木) 20:32
by sor
みけCATさんありがとうございます。
無事、コンパイルでき、理想通りにプログラムを動作させることが出来ました。

Re: 関数テンプレートの明示的特殊化

Posted: 2015年3月05日(木) 21:05
by sor
usaoさんの指摘を間違えて捉えていたため、No.3ではコンパイルできませんでしたが、
正しく解釈し、ソースコードを修正したところ、理想通りに動作しました。
usaoさんありがとうございました。

コード:

#include<iostream>
#include<cstring>

using namespace std;

template <class Type> Type minof(Type x[], int n)
{
  Type min = x[0];

  for(int i = 1; i < n; i++)
    if(x[i] < min)
      min = x[i];

  return min;
}

template <> const char* minof<const char*>(const char* p[], int n)
{
  int min = 0;

  for(int i = 1; i < n; i++)
    if(strcmp(p[i], p[min]) < 0)
      min = i;

  return p[min];
}

int main()
{
  const int n1 = 4;
  int n[n1];
  double d[n1];
  char s[n1][16];

  for(int i = 0; i < n1; i++){
    cout << "整数[" << i << "] : "; cin >> n[i];
  }

  for(int i = 0; i < n1; i++){
    cout << "実数[" << i << "] : "; cin >> d[i];
  }

  for(int i = 0; i < n1; i++){
    cout << "文字列[" << i << "] : "; cin >> s[i];
  }

  const char *pStrs[n1] = { s[0], s[1], s[2], s[3]};

  cout << "最小の整数  : " << minof(n,n1) << "\n";
  cout << "最小の実数  : " << minof(d,n1) << "\n";
  cout << "最小の文字列: " << minof<const char*>(pStrs,n1) << "\n";
}