选择具有不同模板参数的模板类构造函数并导致编译失败

时间:2017-05-03 14:23:25

标签: c++ c++11 templates constructor

这是一个最小的例子,假设我有一个矢量类,其大小可以静态确定或动态确定。我允许构造函数使用不同的语法,如下例所示。

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,则任务看起来非常令人生畏。

1 个答案:

答案 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对于这个实现变得毫无意义,它们永远不会被解雇。但总有一个构造函数是可调用的,取决于模板参数。调用不正确的构造函数会导致编译失败。

LIVE