【发布时间】:2017-09-25 11:14:34
【问题描述】:
我第一次尝试std::enable_if 并且正在苦苦挣扎。任何指导将不胜感激。
作为一个玩具示例,这是一个简单的静态 vector 类,我想为其定义一个复制构造函数,但其行为取决于向量的相对大小:
- 只需将数据复制到更小或相同大小的向量中
- 将数据复制到更大的向量中,然后用零填充其余部分
所以vector 类是:
template <size_t _Size>
class Vector
{
double _data[_Size];
public:
Vector()
{
std::fill(_data, _data + _Size, 0.0);
}
const double* data() const
{
return _data;
}
// ...
};
复制构造函数应该支持这样的事情:将v3的前2个元素复制到v2中:
Vector<3> v3;
Vector<2> v2(v3);
我为行为 1 尝试了一个复制构造函数。像这样,它可以编译:
template <size_t _OtherSize,
typename = typename std::enable_if_t<_Size <= _OtherSize>>
Vector(const Vector<_OtherSize>& v) : Vector()
{
std::copy(v.data(), v.data() + _Size, _data);
}
但编译器无法将此与行为 2 区分开来。即使 enable_if 条件是互斥的。
template <size_t _OtherSize,
typename = typename std::enable_if_t<_OtherSize < _Size>>
Vector(const Vector<_OtherSize>& v) : Vector()
{
std::copy(v.data(), v.data() + _OtherSize, _data);
std::fill(_data + _OtherSize, _data + _Size, 0.0);
}
我也尝试将enable_if 放在参数中,但无法推断出_OtherSize 的值:
template <size_t _OtherSize>
Vector(const typename std::enable_if_t<_Size <= _OtherSize,
Vector<_OtherSize>> & v)
: Vector()
{
std::copy(v.data(), v.data() + _Size, _data);
}
这样做的方法是什么(使用enable_if,而不是简单的if 语句)?
【问题讨论】:
-
根据定义,复制构造函数不能是模板。您可以拥有一个复制的模板化构造函数,但它仍然不是复制构造函数。 ;-]
-
这不是问题,但是以下划线开头的名称后跟大写字母(
_Size、_OtherSize)和包含两个连续下划线的名称保留供实现使用.不要在你的代码中使用它们。 -
不相关,但在
std::enable_if_t之前不需要typename。
标签: c++ templates sfinae enable-if