根据编译时参数使方法可用

时间:2013-03-18 16:13:35

标签: c++ c++11

有没有办法编译方法,取决于模板参数? 我正在尝试创建一个可以处理2,3或更多维度的Coordinate类。我想提供x()y()z()的访问方法,但我希望只有当维度大于3时才能访问z()方法。您可以在下面看到),我使用static_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];
    }
};

我想要做的是隐藏维度2 z()的存在,以便

Coord<int, 2> ci2(0,0);
ci2.z() = 3;   // shouldn't compile
如果不使用static_assert,

不会编译。 我见过很多关于std :: enable_if的问题,但据我所知,它是用来启用或禁用特定的重载。

问题是:是否有办法根据编译时参数使方法可用?

3 个答案:

答案 0 :(得分: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];
    }
};

答案 1 :(得分: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];
    }
};

您可以将共享成员提升到单独的结构中,以防止代码重复。

答案 2 :(得分: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!
}