Reputation: 10425
So, I'm looking for a way to cause a compile-time error if the value used in declaring the object is equal to another value (don't wish to use C's assert
macro).
Yes, I know why the problem occurs... The compiler was quite clear when he/she complained expression did not evaluate to a constant
.
I also don't want to make my entire class a template. Is there a little miracle workaround that I'm missing?
#include <iostream>
class test
{
private:
template<class T, class T2>
using both_int = std::enable_if_t<std::is_integral<T>::value && std::is_integral<T2>::value>;
private:
int _a, _b;
public:
template<class T, class T2 = T, class = both_int<T, T2>>
constexpr test(const T &a, const T2 &b = 1)
: _a(a), _b(b)
{
static_assert(b != 0, "Division by zero!");
}
};
int main()
{
test obj(1, 0); //ERROR
test obj2(0, 1); //OK
std::cin.get();
}
Upvotes: 1
Views: 1655
Reputation: 9404
You can do it like this:
struct test {
private:
constexpr test(int a, int b) {}
public:
template<int b>
static test construct(int a) {
static_assert(b != 0, "not zero failed");
return test(a, b);
}
};
int main()
{
test foo = test::construct<1>(1);
test foo = test::construct<0>(1);//compile error
}
You need static constructor, because of there is no way to specify parameters of template constructor, see C++ template constructor
Upvotes: 2