关于 c :对于类模板,std::enable_if 比 static_assert 有什么优势? | 珊瑚贝

What is the advantage of std::enable_if over static_assert for class templates?


我想知道 std::enable_if 在防止模板实例化方面优于 static_asserts 的优势。这个答案表明,std::enable_if 允许 SFINAE,这在函数模板的情况下是一个令人信服的论点。

但是这个参数对于类模板(和变量模板)是否合法?据我所知,那里没有涉及过载解决方案,这使得 SFINAE – 再次,据我所知 – 不相关,但我可能错了。如果是这样,你能举个例子吗?

如果不是,我认为 static_assert 对于类模板的给定问题(防止模板实例化)是更好的解决方案,因为它可以说更加明确、简洁和易读,并允许自定义错误消息.这是正确的还是我错过了 SFINAE 以外的一点?

  • 如果条件不成立,static_assert 不会阻止实例化。相反,它使程序格式错误。
  • @艾略特嗯…
  • @Elliott标准是这样说的。 “如果转换后表达式的值为真,则声明无效。否则,程序是非良构的”


如您所说,可以通过专门化来处理几种不同的类型:

1
2
3
4
5
6
7
8
template <class>
class foo;

template <>
class foo <int> { /* int implementation */ };

template <>
class foo <char> { /* char implementation */ };

现在考虑我们想要特化多种类型,并且我们希望 float 和 double 属于同一个特化。如果没有 SFINAE,我们无法做到这一点,所以为了避免重复实现,我们使用继承:

1
2
3
4
5
6
7
8
9
class foo_fp_implementation {
    /* specialise for all floating point */
};

template <>
class foo <float> : foo_fp_implementation {};

template <>
class foo <double> : foo_fp_implementation {};

到目前为止,我们一直在避免使用 SFINAE,但是如果您想要一个使用特定接口的所有类型的专业化怎么办?示例:有方法 int bar ()?我们可以尝试使用上述技巧并列出所有可能的类型,但是如果要维护的类型太多,或者您希望其他可能使用自己的类型的人可以使用它怎么办。 SFINAE 来救援了:

1
2
3
4
5
6
7
8
9
template <class, class = int>
class foo;

template <class T>
class foo <T, decltype(T().bar())> {
    // implement using bar interface
};

// other specialisations…

在上述情况下,static_assert根本没办法。

总之,SFINAE 有助于基于精确行为而不是精确类型进行专门化。

  • “更清晰、更简单”(在没有重载的情况下)并且不会导致类似于在函数重载解析中阻止 SFINAE 的一些缺点,对吗?
  • Nvm,我意识到我之前的评论是用双重标准衡量的。如果我的目标不是重载,那么在函数模板中使用 static_assert 也没有缺点。所以类和函数模板的类比是相当完整的。
  • @Reizo,是的,我对你的问题有点困惑。如果您使用 static_assert 而不是 enable_if 那么它将阻止您进行重载(仅基于该模板[您仍然可以基于其他参数/??模板重载])


However is this argument legitimate for class templates (and variable templates)? As far as I know, there is no overload resolution involved there, making SFINAE – again, as far as I know – not relevant, but I might be wrong. If so, can you name an example?

您可以对课程模板进行专业化,并且 SFINAE 可用于在专业化之间进行选择。它还将阻止此类(到那时,可能是格式错误的)类/其专业化的实例化,而不是由于 static_assert.

而无法编译

  • 我不知道模板类型规范如何模棱两可,需要在 [可能的] 专业化之间进行选择。您能否在答案中添加一个示例?


std::enabled_if 在 SFIANE 中用于模板类、方法和…的特化。
static_assert 用于在编译时检查合约,并提供有用的错误消息。


来源:https://www.codenong.com/63668997/

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?