テンプレート引数に、テンプレート関数を指定する方法 – プログラミング – Home

テンプレート引数に、テンプレート関数を...
 
通知
すべてクリア

[解決済] テンプレート引数に、テンプレート関数を指定する方法

固定ページ 1 / 2

Orange
 Orange
(@Orange)
ゲスト
結合: 14年前
投稿: 14
Topic starter  

お世話になります
WinXP(SP3) VC++2008 Express で開発しております
テンプレート引数に、テンプレート関数を指定する方法が分かりません
教えて頂けないでしょうか

template <class T>
void a()
{
...
}

template < void (*f1)(), void (*f2)(), void (*f3)() > // 型ごとに指定
void b()
{
f1();
f2();
f3();
}

template < ?? > // テンプレート関数の指定方法がわからない
void c() {
f<bool>();
f<int>();
f<float>();
}

int main(void)
{
b<a<bool>, a<int>, a<float>>(); // 型ごとに引数を指定するのは面倒
c<a>(); // テンプレート関数を引数に指定できれば、a
だけで済むはず?
}


引用未解決
トピックタグ
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 21年前
投稿: 600
 

> c<a>();

aは型じゃありませんょ?


返信引用
Orange
 Orange
(@Orange)
ゲスト
結合: 14年前
投稿: 14
Topic starter  

a<bool>やa<int>は、関数ポインタ型だから指定できて、
aだけだと、なんだか分からないから指定できない

つまりは、a<bool>やa<int>は、サイズがもとまるから指定できて、
aだけだと、サイズがもとまらないので指定できない

要するに、テンプレート引数には、型(サイズがもとまるもの)しか指定できない

ということでよろしいのでしょうか?


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 21年前
投稿: 600
 

> ということでよろしいのでしょうか?

ぜんぜんちがいます。

int i; があったとき、
a<int>() て書くでしょ?
a<i>() とは書かんでしょ?

でも iのサイズは自明でしょ?
「サイズが求まらないから」ではありません。
型ではないからです。


返信引用
Orange
 Orange
(@Orange)
ゲスト
結合: 14年前
投稿: 14
Topic starter  

すみません型の認識がよく分かっていないようです

テンプレート関数は型ではないということなのでしょうか?

また、とんちんかんなこといっていたらすみません


返信引用
Orange
 Orange
(@Orange)
ゲスト
結合: 14年前
投稿: 14
Topic starter  

> a<int>() て書くでしょ?
> a<i>() とは書かんでしょ?

intは型だからOK、iは変数だからNGってことでよろしいでしょうか?


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 21年前
投稿: 600
 

です。

質問に戻って、a は関数です。型じゃありません。


返信引用
Orange
 Orange
(@Orange)
ゲスト
結合: 14年前
投稿: 14
Topic starter  

ありがとうございます
なるほどー、aは関数なので指定できない事は理解できました。

そうすると、また一つの疑問が出てきます

void d()
{
...
}

template< void (*f)() >
void e()
{
}

int main(void)
{
e<d>();
}

この場合、dは関数だと思うのですが、テンプレート引数に指定できるのはなぜでしょうか?
dは型になるけど、aは型にはならないということなのでしょうか?

質問を重ねてすみません、よろしければお教えください


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 21年前
投稿: 600
 

template<class ...> や template<typename ...> の場合<>に入るのは型ですが、
template<int N> であれば <10> のように値を指定できます。

template< void (*f)() > に求められるtemplate引数は関数へのポインタ(つまり値)
となるわけです。


返信引用
Orange
 Orange
(@Orange)
ゲスト
結合: 14年前
投稿: 14
Topic starter  

なるほど、理解出来ました

関数ポインタなので、値の指定になり
dはポインタを返せるけど、aだとポインタを返せないのでテンプレート引数に指定できな
いということですね

  void (*f0)() = a; // 関数の実体がない(実体を作りようがない)から
// ポインタを返せない
  void (*f1)() = a<bool>; // 関数の実体ができるのでポインタを返せる
  void (*f2)() = d; // 関数なのでポインタを返せる

私の、とんちんかんな質問に貴重な時間を割いていただき
まことにありがとうございました


返信引用
Orange
 Orange
(@Orange)
ゲスト
結合: 14年前
投稿: 14
Topic starter  

蛇足ですが、D言語だと alias 引数を使ってあっさり書けそうですね

void a(T)()
{
printf(a() %d\n, T.sizeof);
}

void b( alias C )()
{
C!(bool)();
C!(int)();
C!(double)();
}

int main(char[][] args)
{
b!(a)();
return 0;
}


返信引用
Orange
 Orange
(@Orange)
ゲスト
結合: 14年前
投稿: 14
Topic starter  

色々悩んだ結果

テンプレート関数だから指定できないということなので、
テンプレートクラスに変更することにしました
(本当は関数のままがいいんですけど…)

// 仕方なくテンプレートクラスに変更
template < class T >
class a
{
public:
void operator()()
{
printf(a() %d\n, sizeof(T));
}
};

template < template<class T> class C >
void b()
{
C<bool>()();  // この呼び出しって正しいのかな?
C<int>()();
C<double>()();
}

int main(void)
{
b<a>();
return 0;
}


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

> // この呼び出しって正しいのかな?
技術的には正しい。
一時オブジェクトを作って、呼び出しだけして、即時デストラクト。
この動作に意味があるのか?と問われて、意味があるかどうかは知らない。
(俺ならやらない)

この手の話は、単純に技術論だけに終始させてもいいんだけど
「なぜこういう呼び出しがしたいのか」あたりから始めると、
もっと根幹的な代案が出るかもしれない(し、出ないかもしれない)


返信引用
Orange
 Orange
(@Orange)
ゲスト
結合: 14年前
投稿: 14
Topic starter  

επιστημηさん
tetrapodさん
回答ありがとうございました。

事の始まりは、
「型が違う所以外は同じ処理をする関数を次々に呼び出す処理」が必要になったので、
(本当に必要なの?という突っ込みはなしでw)
テンプレートを使って書こうと思ったのがきっかけでした。

最初、こんなのさっくり書けるだろうと思ったのですが、、、
なんか思ってるようにうまく書けない。

色々悩んだ結果、
「テンプレート引数に、テンプレート関数が指定できたらうまく書けるのでは?」
と思い、書き方が分からないので質問させていただいた次第です

結果、
「そんなもんは、テンプレート引数に指定できないぞ」
ということを教えていただき、それならばと思い、関数をクラスに、、、
と無理矢理な実装になりつつあります(汗
少々、b<a>の形にこだわりすぎなのかもしれません。

最終的に思うことは、「C++0xに、alias 引数を希望しますw」


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

傍観していましたけれど、テンプレート関数aを作成する事に関しては
意義を感じますけれど、テンプレート関数bに関してはホントに必要なの?
と感じました。

テンプレート関数化すると言うのは、処理の汎用化にあると思うので
次々と呼び出す部分まで汎用化するメリットってあるの?
と言うのが本音ですね。
呼び出し部分は普通に記述すれば良いだけじゃないかと思っています。
多分、その方がソースを見た時に何をやっているのかはわかりやすいと
思うので。

もちろん、ソースを見る人が
関数aが何をする関数なのかを知っている前提になりますけれど。


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました