是否可以将static_assert
与模板别名结合使用?我了解如何将SFINAE与模板别名一起使用,以及如何将static_assert
与struct
一起使用,但是我希望将static_assert
与别名一起提供更清晰的错误消息。
我想到了以下用例:
#include <array>
constexpr bool is_valid(int n){
return n <= 10;
}
template <int n>
struct Foo {
static_assert(is_valid(n), "This class cannot handle more than 10 dimensions");
};
template <int n>
using Bar = std::array<float,n>;
template <int n, std::enable_if_t<is_valid(n)> * unused = nullptr>
using BarSFINAE = std::array<float,n>;
int main() {
Foo<5>();
// Foo<20>(); // Triggers the compiler-time static_assert
Bar<5>();
Bar<20>(); // TODO: Should trigger a compiler-time static_assert
BarSFINAE<5>();
// BarSFINAE<20>(); // Not allowed due to SFINAE, but throws an ugly compile time message
}
问题本质上是别名没有主体。因此,我什至不知道将static_assert
放在哪里。
答案 0 :(得分:5)
正确识别问题后,解决方案是添加一些别名可以依赖的正文。例如,一个函数。
namespace detail {
template<std::size_t N>
constexpr auto checked_size() {
static_assert(is_valid(N), "");
return N;
}
}
template <int n>
using Bar = std::array<float, detail::checked_size<n>()>;
答案 1 :(得分:2)
是的,您可以通过使用如下辅助结构来实现:
template<typename T>
struct A {};
template<int n, typename T>
struct B_impl {
static_assert(n <= 10,
"this is a demonstration");
using type = A<T>;
};
template<int n, typename T>
using B = typename B_impl<n, T>::type;
using B_good = B<3, int>;
using B_bad = B<11, int>;
int main() {
B_good good; // works
B_bad bad; // static assertion failure
}