这是一个最小的例子,假设我有一个矢量类,其大小可以静态确定或动态确定。我允许构造函数使用不同的语法,如下例所示。
template<int RowAtCompileTime>
class Vector{
//Other Details
int rowNumber;
public:
//For vectors with size known at compile time
Vector(){
static_assert(RowAtCompileTime > 0,"Cannot do this");
rowNumber = RowAtCompileTime;
}
//For vectors with dynamic size
Vector(const int _rowNumber){
static_assert(RowAtCompileTime<=0, "Cannot do this");
rowNumber=_rowNumber;
}
};
template class Vector<0>;
template class Vector<1>;
int main(){
//do nothing
return 0;
}
根据语法,目标是这样 - 只有一个构造函数应该是可调用的。假设模板参数RowAtCompileTime
小于0,这意味着它是动态的,只有构造函数Vector(const int _rowNumber)
应该是可调用的。
代码不会在gd = c ++ 11下的g ++ - 4.8下编译,这是预期的,因为构造函数将根据this实例化所有接口。它似乎来自同一个网站,也不可能通过SFINAE传递这个(但是,我对这个概念很新,我不确定这是否属实)。可以提供部分模板特化,但如果有许多参数如RowAtCompileTime
,则任务看起来非常令人生畏。
答案 0 :(得分:1)
SFINAE可以;它只适用于函数模板,因此我们需要制作构造函数模板:
//For vectors with size known at compile time
template <int V = RowAtCompileTime, typename = std::enable_if_t<(V > 0)>>
Vector() {
rowNumber = V;
}
//For vectors with dynamic size
template <int V = RowAtCompileTime, typename = std::enable_if_t<(V <= 0)>>
Vector(const int _rowNumber) {
rowNumber = _rowNumber;
}
然后
Vector<0> v1(10);
Vector<1> v2;
BTW:static_assert
对于这个实现变得毫无意义,它们永远不会被解雇。但总有一个构造函数是可调用的,取决于模板参数。调用不正确的构造函数会导致编译失败。