Reputation: 303
Here is a minimal example, suppose that I have a vector class whose size can be either statically determined or dynamically determined. I allow different syntax for constructors like in the following example.
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;
}
Depending on the syntax, the goal is so-that only one of the constructor should be callable. Assume that the template parameter RowAtCompileTime
is less than 0, which means it is dynamic, only the constructor Vector(const int _rowNumber)
should be callable.
The code will not compile under g++-4.8 under std=c++11, which is expected, as the constructor will instantiate all the interfaces according to this. It seems from the same website it is not possible to pass through this via SFINAE either (however, I am quite new to this concept, and I am not sure whether this is true). It is possible to offer partial template specializations, but if there many parameters like RowAtCompileTime
the task seems very daunting.
Upvotes: 1
Views: 97
Reputation: 172934
It's possible with SFINAE; which only works with function templates, so we need to make the constructors template:
//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;
}
then
Vector<0> v1(10);
Vector<1> v2;
BTW: static_assert
s become meaningless for this implementation, they'll never be fired. But there's always only one constructor being callable, depends on the template argument. Call to improper constructor would cause compilation fail.
Upvotes: 1