5

2つのスタイルのデータのどちらを含めるかを決定するテンプレートパラメータを持つクラスがあります。そのパラメーターに基づいて、2つの異なる方法のいずれかでメンバー関数を実装したいと思います。Boost Enable-Ifを使用してみましたが、成功しませんでした。これが私が最も驚いたコードのバージョンが機能しないことです:

#include <boost/utility/enable_if.hpp>
enum PadSide { Left, Right };
template <int> struct dummy { dummy(int) {} };

template <PadSide Pad>
struct String
{
    typename boost::enable_if_c<Pad ==  Left, void>::type
        getRange(dummy<0> = 0) {}
    typename boost::enable_if_c<Pad == Right, void>::type
        getRange(dummy<1> = 0) {}
};

int main()
{
    String<Left> field;
    field.getRange();
}

これに対して、g++4.6.0は次のように述べています。

no type named ‘type’ in ‘struct boost::enable_if_c<false, void>’

もちろん、2番目のオーバーロードは機能しないはずですが、SFINAEのために無視されるはずです。ダミー関数パラメーターを削除すると、g++は次のように言います。

‘typename boost::enable_if_c<(Pad == Right), void>::type
    String<Pad>::getRange()‘
cannot be overloaded with
‘typename boost::enable_if_c<(Pad == Left), void>::type
    String<Pad>::getRange()‘

そのため、最初にダミーパラメータを配置しました。ドキュメントの「コンパイラの回避策」セクションに従ってください。

基本的に私が欲しいのは、getRange()の2つの実装を持ち、Padタイプに基づいてどちらかを選択することです。私は、Enable-Ifが、作業を委任するための補助クラスを作成せずにそれを実行できるようになることを望んでいました(これについては、その間に試してみます)。

4

1 に答える 1

7

getRange()とにかくの 2 つの異なるバージョンを作成するためstruct String、 のタイプに応じてメンバー関数をいつでもオーバーロードできますPadSide。それほど「きれい」ではないことはわかっていますが、最終的には同じ量のコードであり、複数のクラス タイプを作成する必要はありません。

template<PadSide Pad>
struct String
{
    void getRange();
};

template<>
void String<Right>::getRange() { /*....*/ }

template<>
void String<Left>::getRange() { /*....*/ }
于 2011-07-14T15:56:53.910 に答える