【问题标题】:Compiler error with a fold expression in enable_if_tenable_if_t 中带有折叠表达式的编译器错误
【发布时间】:2019-07-10 20:54:43
【问题描述】:

我有以下代码,其中我使用折叠表达式来评估是否所有包参数都可以转换为第一个函数参数。由于某种原因,当我进行看似非常微不足道的更改时,它无法在 msvc 上编译:

#include <type_traits>

#define TRY 1

#if TRY == 1

template<typename B, typename... Args,
std::enable_if_t<((std::is_convertible_v<Args&, B&> && ...)), bool> = true>
void fn(B b, Args...args) {}

#else

template<typename B, typename... Args,
typename = std::enable_if_t<(std::is_convertible_v<Args&, B&> && ...)>>
void fn(B b, Args...args) {}

#endif

int main()
{
    fn(5, 4, 2);
    return 0;
}

TRY 更改为0 进行编译,演示地址:https://godbolt.org/z/EGvQ-N

我遗漏的两个变体之间是否存在重要区别,或者这是编译器错误?

【问题讨论】:

  • 我相信这是 MSVS 的解析问题。一两个月前有一个这样的问题,我会尝试查找,看看是否发现了这个问题
  • 好吧,我找到了post I was thinking of,但它使用的是数组而不是折叠表达式。可能是同一个问题,也可能不是。
  • @NathanOliver 那是一年前的事了,即使是同一个问题,也意味着要么没有报告,要么他们没有修复它。我向 MS 提交了错误报告,希望他们能修复它。
  • 那是上个月的。 6 月 18 日不是 2018 年 6 月,而是 6 月 18 日。
  • 如果是从去年 6 月 18 日开始,则应该是 2018 年 6 月 18 日。

标签: c++ templates c++17 enable-if fold-expression


【解决方案1】:

冒着偏离主题的风险,我不确定折叠表达式是这里的最佳选择。我鼓励您使用 MSVS 支持的 std::conjunction 变体:

- std::enable_if_t<((std::is_convertible_v<Args&, B&> && ...)), bool> = true>
+ std::enable_if_t<std::conjunction_v<std::is_convertible<Args&, B&>...>, bool> = true>

的确,它更冗长,但可能更清晰。我遵从@NathanOliver 来追踪最初询问的潜在 MSVS 错误。

(本来可以把它作为评论,但认为代码块更清晰。)

【讨论】:

  • 我最初是想至少让一些东西起作用,这样确实有很大帮助。我想我会用 msvc 提交另一个编译器错误(不幸的是,这是本周的第三个错误)。
  • 我不同意。我发现折叠表达式更清晰。这是一个简单的案例,每个程序员都知道&amp;&amp; 是什么,但是“连接”需要一些思考,也许需要一些谷歌搜索才能弄清楚。 IMO,conjunction 仅在您需要短路时才真正值得。
  • @Justin 并不是每个程序员都知道折叠表达式是什么。如果有人实际上不知道什么是连词,那么无论哪种方式查找它都可能是个好主意。我的观点是,它看起来更好是主观的。我更喜欢折叠只是因为我习惯了 Haskell 并且我不喜欢太多的&lt;&gt;,但这并不是说它优于其他变体 imo。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多