有没有办法编译方法,取决于模板参数?
我正在尝试创建一个可以处理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的问题,但据我所知,它是用来启用或禁用特定的重载。
问题是:是否有办法根据编译时参数使方法可用?
答案 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!
}