6

テンプレート引数に応じて、メソッドをコンパイルする方法はありますか? 2、3、またはそれ以上の次元を処理できる Coordinate クラスを作成しようとしています。x()accesses メソッドを、y()およびとして提供したいのですが、次元が 3 より大きい場合にのみメソッドにアクセスできるz()ようにしたいと考えています。今のところ (以下に示すように)、次元 2 の座標に を使用できないようにするためにa を使用しています。z()static_assertz()

template<typename DataType, int Dimension>
class Coord
{
private:
    std::array<DataType, Dimension> _data;

public:

    // how to achieve some kind of compile_if()
    DataType& z()
    {
        static_assert(Dimension >= 3, "Trying to access an undefined dimension.");
        return _data[2];
    }
};

私がやりたいのはz()、次元2の存在を隠すことです。

Coord<int, 2> ci2(0,0);
ci2.z() = 3;   // shouldn't compile

static_assert を使用しないとコンパイルされません。std::enable_if に関する多くの質問を見てきましたが、私が理解しているのは、特定のオーバーロードを有効または無効にするために使用されることです。

質問は: コンパイル時の引数に応じて、メソッドを使用可能にするかどうかを決定する方法はありますか?

4

3 に答える 3

8

たとえば、関数をテンプレートとして宣言し、次のstd::enable_ifように使用できます

template<typename DataType, int Dimension>
class Coord
{
private:
    std::array<DataType, Dimension> _data;

public:
    template <class T = DataType>
    typename std::enable_if<Dimension >= 3, T&>::type
    z()
    {
        return _data[2];
    }
};
于 2013-03-18T16:38:20.320 に答える
6

これには特殊化を使用できます。

template<typename DataType, int Dimension, bool HaveZ = (Dimension >= 3)>
class Coord;

template<typename DataType, int Dimension>
class Coord<DataType, Dimension, false>
{
private:
    std::array<DataType, Dimension> _data;

public:
};

template<typename DataType, int Dimension>
class Coord<DataType, Dimension, true>
{
private:
    std::array<DataType, Dimension> _data;

public:

    DataType& z()
    {
        return _data[2];
    }
};

コードの重複を防ぐために、共有メンバーを別の構造体に持ち上げることができます。

于 2013-03-18T16:20:41.157 に答える
3

スペシャライゼーションスペシャライゼーションに基づいてこのアプローチを使用できます。

#include <array>

template<typename DataType, int Dimension, bool = (Dimension < 3)>
class Coord
{
protected:
    std::array<DataType, Dimension> _data;
};

template<typename DataType, int Dimension>
class Coord<DataType, Dimension, false> : public Coord<DataType, Dimension, true>
{
public:
    DataType& z()
    {
        return this->_data[2];
    }
};

int main()
{
    Coord<double, 3> c3;
    c3.z(); // OK

    Coord<double, 2> c2;
    c2.z(); // ERROR!
}
于 2013-03-18T16:31:04.373 に答える