ページ 11

【TMP(?)】クラスのテンプレート引数でメンバ関数を特殊化

Posted: 2012年12月06日(木) 03:16
by SUE
久しぶりの質問です。

コード:

template< bool isEnable >
struct A{

	template< bool isEnable >//クラスのテンプレート引数と一致している
	void	func(){ cout << "メンバにアクセスする何らかの処理"; }

	template<>
	void	func< false >(){ cout << "多分、エラーを吐く処理"; }

	/*その他とても多くの関数など…*/
};

int main(){

	A< true > object;
	object.func();//エラー!
	return 0;
}
上のコードの様な形で、クラスに渡したテンプレート引数を使ってそのメンバ関数を切り替えたいのですが、テンプレート引数を減少できませんなどと叱られてしまいます。
どう修正すればよいでしょうか。ご教示願います。

Re: 【TMP(?)】クラスのテンプレート引数でメンバ関数を特殊化

Posted: 2012年12月06日(木) 09:00
by beatle
ちょっと面倒かもしれませんが、クラスA全体をfalseの場合に特殊化するのはどうでしょうか。

Re: 【TMP(?)】クラスのテンプレート引数でメンバ関数を特殊化

Posted: 2012年12月06日(木) 09:55
by YuO
解決方法はbeatleさんの書かれている通りだとして……。

クラステンプレート中の関数テンプレートのテンプレート引数は,クラステンプレートと同名の引数であっても別物です。
なので,エラーの原因になっている関数の呼び出しは,

コード:

object.func<true>();
のように書かなければいけません。

ここで,本来の目的が,この関数テンプレートの引数であるtrueとobjectのクラスのテンプレート引数が等しい,というのであれば,

コード:

template <bool isEnabled>
struct A
{
private:
    template <bool> void func_impl (void) { /* 本来の実装(isEnabled == isFuncEnabled) */ }
    template <> void func_impl<false> (void) { /* 本来の実装(isEnabled != isFuncEnabled) */ }
public:
    template <bool isFuncEnabled> void func (void) { func_impl<isEnabled == isFuncEnabled>(); }
};
のように,1段階関数を経由する必要があります。

Re: 【TMP(?)】クラスのテンプレート引数でメンバ関数を特殊化

Posted: 2012年12月06日(木) 18:46
by GRAM
ぶっちゃけ、引数のtrue or falseによって呼び出す関数を変えたいだけならこれだけなきが・・・

コード:

#include <iostream>

using namespace std;

template< bool isEnable >
struct A{
    void  func();
    /*その他とても多くの関数など…*/
};

template<>
void A<true>::func()
{
	cout << "なんか処理" << endl;
}

template<>
void A<false>::func()
{
	cout << "エラー?" << endl;
}
 
int main(){
 
    A< true > object;
    object.func();

	A< false > object2;
    object2.func();//エラー!
    return 0;
}

Re: 【TMP(?)】クラスのテンプレート引数でメンバ関数を特殊化

Posted: 2012年12月07日(金) 02:22
by SUE
返信送れて申し訳ありません。みなさんありがとうございました。
>beatleさん
綺麗な解決法がなければ、所詮はtrueとfalseしかないんだしコピペしてもいいかな、なんて一瞬考えましたが、実際の実装では1クラスに同じ仕組みを何個か入れる予定なので、
2^n回もコピーするのは割りと洒落にならないな・・・と思いました。もし本当にコピペするしかなかったら諦めて動的に解決するつもりでした。

>YuOさん
その実装で行くとかなり面倒くさそうですね・・・結局本来の目的ともずれてしまう気が。ただ、テンプレート引数を渡すときに条件文を書けるというのを初めて知りました。
この辺まだまだ勉強不足だなと思わされた次第です。

>GRAMさん
一種のアハ体験をさせられたような気分でいます、なるほど外に定義を書いて特殊化すればいいんですね。大変参考になりました。
GRAMさんには扱う領域が被っているからか質問する度にお世話になっていますが、今回も答えていただいてありがとうございました。