![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
C++の関数テンプレートで分からないところがあります。
C++の入門書を読んで勉強しているのですが、その演習問題(答えはついてないです)で、以下のような問題がありました。
-----------------------------------------------------
配列の全要素の最小値を求める関数テンプレートを作成せよ。
teplate <class Type> Type minof(const Type x[], int n);
という形で作ること。
なお、最も小さい文字列を求められるようにするために、const char *型に明示的に特殊化したものも合わせて作成すること。
------------------------------------------------
という問題なのですが、これにたいして僕は以下のように答えました。ヘッダのインクルードなどは省きます。
template<class Type> Type minof(const Type x[], const int n)
{
int min = 0;
for(int i = 1; i < n; i++)
if(x[min] < x[i])
min = i;
return x[min];
}
template<> const char* minof<const char *>(const char x[][64], const int n)
{
int min = 0;
for(int i = 1; i < n; i++)
if(strcmp(x[min], x[i]) < 0)
min = i;
return x[min];
}
int main()
{
const int n = 5;
int a[n];
char s[n][64];
for(int i = 0; i < n; i++){
cout << i + 1 << "番目---";
cin >> a[i];
}
cout << "文字列\n";
for(int i = 0; i < n; i++){
cout << i + 1 << "番目---";
cin >> s[i];
}
cout << "整数の最小値---" << minof(a, n) << "です\n";
cout << "文字列の最小値---" << minof<const char *>(s, n) << "です\n";
}
これをコンパイルすると、エラーで
明示的な特殊化; 'const char *minof<const char*>(const char [][64],const int)' は関数テンプレートの特殊化ではありません
と
'minof' : 1 番目の引数を 'char [5][64]' から 'const char *const []' に変換できません。
とでてしまいます。
色々探してみたのですが、解決できませんでした・・。
特に最初のほうのエラーがよくわかりません。ちゃんと特殊化してる気はするのですが・・。
間違っている箇所の正当を載せていただけるとわかりやすくて、ありがたいです。
よろしくお願いします!
No.4ベストアンサー
- 回答日時:
> template <class Type> Type minof(const Type x[], int n)
という形で作ることと、
> const char *型に明示的に特殊化したもの
を作ることという要求に近いものとしては、
#include <iostream>
template <typename Type> Type minof(const Type x[], const int n)
{
int min = 0;
for(int i = 1; i < n; i++) if(x[min] > x[i]) min = i;
return x[min];
}
template <> const char* minof<const char*>(const char* const x[], const int n)
{
int min = 0;
for(int i = 1; i < n; i++) if(strcmp(x[min], x[i]) > 0) min = i;
return x[min];
}
int main()
{
const int n = 5;
int a[n];
char* s[n];
for(int i = 0; i < n; i++){
std::cout << i + 1 << "番目---";
std::cin >> a[i];
}
std::cout << "文字列\n";
for(int i = 0; i < n; i++){
std::cout << i + 1 << "番目---";
s[i]=new char[64];
std::cin >> s[i];
}
std::cout << "整数の最小値---" << minof(a, n) << "です\n";
std::cout << "文字列の最小値---" << minof<const char *>(s, n) << "です\n";
}
とか?
> char s[n][64];
はテンプレートに合わせるためにchar*の配列に修正している。
各char*の領域はプログラムはすぐ終わるしnewしてdeleteはしてない。
あと、比較の不等号の向きは逆だと思うので反転している。
x[min]よりx[i]が小さいときに最小値を更新するのだと思う。
No.5
- 回答日時:
ごめん、補足。
#include <cstring>
の抜けと
for(int i = 1; i < n; i++) if(std::strcmp(x[min], x[i]) > 0) min = i;
にしないと。
g++では特に何もしなくてもコンパイルできてしまったのでつい。
おぉ・・strcmp関数は文字列の先頭のアドレスさえ渡せばいいから、わざわざ多次元配列で作らなくて、new演算子で先頭のアドレスだけ入手すればよかったんですね・・!
まさかこんなところでもnew演算子が役に立つとは思いもしませんでした。
あと、プログラム自体の間違いも指摘していただいて・・
ありがとうございました!
No.3
- 回答日時:
間違ってたので修正のうえ再貼り付け。
#include <iostream>
#include <string.h>
using namespace std;
template <class Type> int less_than( Type x, Type y ){
cout << "DEBUG(G):" << x << "," << y << "=" << (x<y) << endl;
return x < y; }
int less_than( const char *x, const char *y ){
cout << "DEBUG(c*):" << x << "," << y << "=" << strcmp(x,y) << endl;
return strcmp( x, y ) < 0;
}
template <class Type> Type minof( const Type x[], const int n ){
int min = 0;
for( int i = 1; i < n; i++ ) if( less_than( x[i], x[min] ) ) min = i;
return x[min];
}
int main( int argc, char *argv[] ){
const char *a[] = { "test1", "test2", "t3", "test 4", "test No.5" };
cout << "Min of a:" << minof( a, sizeof a/ sizeof *a ) << endl;
const int b[] = { 3,4,2,1,5 };
cout << "Min of b:" << minof( b, sizeof b/ sizeof *b ) << endl;
}
おぉ~、テンプレート関数の中にテンプレート関数を用いて、ムリに一つのテンプレート関数で実現しようとせずにしているわけですか!
この発想はありませんでした・・。
確かにこの方がテンプレート関数の引数が書きやすくていいですね!
なれない多次元配列の受け渡しなどをしてないから分かりやすいです
ありがとうございました
No.2
- 回答日時:
特殊化というのは<class TYPE>のTYPEの部分がある型のときに処理を変えたいということなので、
template<class Type> Type minof(const Type x[], const int n)
の
TYPE部分をconst char*に変えても
template<> const char* minof<const char *>(const char x[][64], const int n)
にはならない。つまり、
template<> const char* minof<const char *>(const char x[][64], const int n)
の一般系(特殊型以外)の定義がないからエラーになるのだと思います。
例えば、
template<class Type> Type minof(Type x[], const int n)
template<> char* minof<char*>(char* x[], const int n)
ならエラーにならないはずです。
(ただし、上記の例をもちいるなら、関数本体も変えなければなりませんが・・・・・・)
なるほど、特殊化にはそのような原理?みたいなものがあるんですね!
ただ単に上のテンプレート関数と同じ名前をしていたら、あとは引数の型とかは自由だと思ってました・・・。
分かりやすく教えてくださってありがとうございました!
No.1
- 回答日時:
一例
#include <iostream>
#include <string.h>
using namespace std;
template <class Type> int less_than( Type x, Type y ){ return x < y; }
int less_than( const char *x, const char *y ){
cout << "DEBUG:" << x << "," << y << "=" << strcmp(x,y) << endl;
return strcmp( x, y ) > 0;
}
template <class Type> Type minof( const Type x[], const int n ){
int min = 0;
for( int i = 1; i < n; i++ ) if( less_than( x[min], x[i] ) ) min = i;
return x[min];
}
int main( int argc, char *argv[] ){
const char *a[] = { "test1", "test2", "t3", "test 4", "test No.5" };
int n = sizeof a / sizeof *a;
cout << "Min of a:" << minof( a, n ) << endl;
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C++プログラミングコードにポリモーフィズムを取り入れ方を教えてください。 2 2023/06/09 11:17
- C言語・C++・C# const char** p;のとき、free(p)でC4090エラーとなるのはなぜですか 3 2023/03/31 16:28
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# Cのdoubleの浮動小数点表示について 3 2023/04/17 13:14
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# Cの関数の引数のconst *charについて 5 2023/04/25 13:05
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
csvファイルからの読み込みがス...
-
半角カナ→16進
-
C言語の質問です
-
カラー画像からグレースケール...
-
switch文で文字を比較すること...
-
文字列の比較について
-
3桁区切(コンマ)記号をつけ...
-
charでの計算?
-
C言語で文字列操作を忘れてしま...
-
干支のプログラム
-
fgetsなどのときのstdinのバッ...
-
char型からのバイト数取得
-
c言語についての質問です。
-
int main()の・・・
-
charからLPTSTRへの変換方法
-
[C++]ファイル出力について
-
c言語の文字列の逆順のプログラ...
-
CStringをwchar_tに変換したい
-
C++の関数テンプレートで分から...
-
文字列について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
C言語のfor文です。 繰り返しの...
-
テキストデータをそのままバイ...
-
charでの計算?
-
文字列から空白を取り除きたい...
-
charからLPTSTRへの変換方法
-
atoi( ) の反対をやりたい
-
2曲同時再生するにはどうした...
-
C言語の入力した文字を反転させ...
-
配列をnビットシフトする
-
3桁区切(コンマ)記号をつけ...
-
int main()の・・・
-
型変換
-
CStringをwchar_tに変換したい
-
'const char *' 型は 'char *' ...
-
間接操作のレベルとは
-
double型の値をchar配列に変換...
-
絶対パスからのファイル名の切...
-
switch文で文字を比較すること...
-
c++ 文字列を入力して、一文字...
おすすめ情報