6

有没有办法编译方法,取决于模板参数?我正在尝试创建一个可以处理 2、3 或更多维度的 Coordinate 类。我想将访问方法提供为x(),y()z(),但我希望z()只有在维度大于 3 时才能访问方法。现在(如下所示),我使用 astatic_assert来防止使用z()维度 2 的坐标。

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 回答