【问题标题】:My type fails an enable_if predicate in a std function. Is there a way to "debug" the predicate?我的类型在 std 函数中的 enable_if 谓词失败。有没有办法“调试”谓词?
【发布时间】:2016-05-04 12:22:45
【问题描述】:

我的问题一般是关于标准库中的 enable_if 谓词,但我将在迭代器类型的上下文中对其进行构建,因为这是我目前遇到此问题的地方。

我有一个自定义迭代器类型It,这样std::iterator_traits<It>::value_type 就是Val。我已经成功地将这种类型与 C++11 之前的标准一起使用,但现在使用 C++11(以及另一个通常更严格的编译器)编译失败了。我的用例之一是insert into a vector 喜欢

std::vector<Val> v; 
It begin = ...
It end = ...   
v.insert(v.end(), begin, end);

编译器拒绝我想要的特定重载候选 insert&lt;_Iter&gt;(iterator, _Iter, _Iter) 的原因是:

no matching member function for call to 'insert'
candidate template ignored: disabled by 'enable_if' [with _Iter = It]

查看&lt;vector&gt; 标头,我看到失败的enable_if 谓词是_Is_Iterator。有没有办法逐步检查谓词条件以找出哪个It 不满足,或者通常有任何方法可以找出此信息而无需手动检查InputIterator 的所有要求(或任何相关概念可能是)一个接一个?

旧编译器(It 适用)是来自 C++ Builder XE8 的 bcc32;新的编译器是 C++ Builder 10.1 中基于 Clang 的 32 位编译器。

【问题讨论】:

  • 也许 templight 可以帮忙。
  • 看起来不错。我试试看。
  • @alcedine 有了encppreference.com 这样的网站,很容易一一检查任何概念的要求。
  • @Holt 并不是很难,而是有很多东西需要检查。

标签: c++ iterator enable-if


【解决方案1】:

您的编译器会尝试告诉您哪个参数是错误的。 Visual Studio 将告诉您与您的规范最匹配的重载以及哪些参数匹配或不匹配。我相信 Clang 和 gcc 也能做到这一点。

一旦您读取了不匹配的参数,您有责任确定编译器是否尝试了正确的重载,以及您的参数如何不匹配。

在大多数情况下,这很简单。但是你对迭代器是正确的,它可能有点令人生畏。但这就是为什么这通常由您的样板文件从iterator 继承来处理的原因。

当您编写迭代器时,您有责任实现继承自的迭代器类别的要求。

insert 要求最后两个参数为“InputIterators”。所以你应该继承自iterator&lt;input_iterator_tag, T&gt; 或更费力的标签之一。一个“InputIterator”被定义为:

  1. 满足“Iterator”所有要求的类型
  2. 类型为“EquallyComparable”
  3. 已定义 reference 和 value_type 成员类型
  4. 定义了不等式运算符
  5. 定义了指针解引用和成员选择运算符
  6. 定义了前置和后置运算符

【讨论】:

  • 恐怕这不是我所问问题的答案。
  • @alcedine 你失败了vector 的enable_if 并且你想逐步完成“InputIterator”的要求,对吧?这些是要求。还是我误解了你的要求?
  • 我的意思是单步调试它们有点像在调试器中单步调试代码,或者只是获取一些更具体的错误信息(例如,“It 不满足 C 的条件 X”,而不是只是“It 不满足 C”)——不从列表中手动检查它们。如果不清楚,请致歉。
  • @alcedine 我已经更新了我的答案。我确定您不是在询问第三方建议(因为 http://stackoverflow.com 禁止此类问题。)所以您的官方回答是:“不,没有办法”但是大多数编译器除了迭代器之外,几乎所有东西都做得很好。对于迭代器,该标准为您提供了大量帮助,您是否正在使用这些帮助?
  • 嗯,您已经在此处扩展了重载解决方案,但这些内容始终很清楚。我知道我正在寻找 insert 的哪个重载,并且我从编译器输出中知道编译器拒绝该重载候选者的原因(请参阅我发布的输出;候选者被 enable_if 禁用)。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多