【发布时间】:2019-07-10 08:42:34
【问题描述】:
是否可以将static_assert 与模板别名结合使用?我了解如何使用带有模板别名的 SFINAE,以及如何使用带有 struct 的 static_assert,但我希望带有别名的 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放在哪里。
【问题讨论】:
-
我很好奇为什么
static_assert只适用于别名。对于仅使用别名类型/模板的人来说,这是一个非常薄的安全层。要么您可以控制别名类型/模板(在这种情况下,只需在那里进行检查?)或者您没有(在这种情况下,您不能轻易阻止其他人忽略您的别名)... -
为什么不直接
template <int n> using Bar = std::enable_if_t<is_valid(n), std::array<float, n>>?顺便说一句,非类型模板参数在 C++14 中不应具有void*类型。 -
@MaxLanghof 我们正在编译一个用于分发的库。显然,用户可以只修改这个头文件并删除静态断言,但是他们会得到奇怪的链接器错误,因为库只是针对特定条件编译的
-
@L.F.我不明白你对 void 的看法*
-
@bremen_matt 使用其他类型,例如
int。