使用 std::enable_if 与复杂谓词。

huangapple go评论92阅读模式
英文:

Using std::enable_if with complex predicates

问题

使用 typename std::enable_if<IsVector<T>::value || IsList<T>::value, void>::type 作为约束条件时,它可以正常工作。如果使用 typename std::enable_if<IsVectorOrList<T>::value>::type,编译器会报错。

如何让它正常工作呢?

英文:

Having to use C++14 I'd like to use std::enable_if to make a function only being available given certain constraints. I do so using or_&lt;&gt; taken from the libc header type_traits instead of std::disjunction (no C++17 available in my environment) in order to move the constraint logic into a separate construct.

However, I seem to be missing something, because I can't manage to get it to compile.

My code:

  1. #include &lt;type_traits&gt;
  2. #include &lt;iostream&gt;
  3. #include &lt;vector&gt;
  4. #include &lt;list&gt;
  5. template &lt;typename T&gt;
  6. struct IsVector : public std::false_type {};
  7. template &lt;typename T&gt;
  8. struct IsVector&lt;std::vector&lt;T&gt;&gt; : public std::true_type {};
  9. template &lt;typename T&gt;
  10. struct IsList : public std::false_type {};
  11. template &lt;typename T&gt;
  12. struct IsList&lt;std::list&lt;T&gt;&gt; : public std::true_type {};
  13. // taken from libc type_traits
  14. template &lt;bool, typename, typename&gt;
  15. struct conditional;
  16. template &lt;typename...&gt;
  17. struct or_;
  18. template &lt;&gt;
  19. struct or_&lt;&gt; : public std::false_type {};
  20. template &lt;typename _B1&gt;
  21. struct or_&lt;_B1&gt; : public _B1 {};
  22. template &lt;typename _B1, typename _B2&gt;
  23. struct or_&lt;_B1, _B2&gt; : public conditional&lt;_B1::value, _B1, _B2&gt;::type {};
  24. template &lt;typename _B1, typename _B2, typename _B3, typename... _Bn&gt;
  25. struct or_&lt;_B1, _B2, _B3, _Bn...&gt; : public conditional&lt;_B1::value, _B1, or_&lt;_B2, _B3, _Bn...&gt;&gt;::type {};
  26. // ---
  27. template &lt;typename T&gt;
  28. struct IsVectorOrList : public or_&lt;IsVector&lt;T&gt;, IsList&lt;T&gt;&gt;::type {};
  29. template &lt;typename T&gt;
  30. typename std::enable_if&lt;IsVector&lt;T&gt;::value || IsList&lt;T&gt;::value, void&gt;::type
  31. // replacing with this line does not work
  32. //typename std::enable_if&lt;IsVectorOrList&lt;T&gt;::value, void&gt;::type
  33. foo(const T&amp; list)
  34. {
  35. for (const auto&amp; item : list)
  36. {
  37. std::cout &lt;&lt; item &lt;&lt; std::endl;
  38. }
  39. }
  40. int main()
  41. {
  42. foo(std::vector&lt;int&gt;{17, 42});
  43. foo(std::list&lt;float&gt;{1.0, 2.71, 3.14});
  44. }

When using typename std::enable_if&lt;IsVector&lt;T&gt;::value || IsList&lt;T&gt;::value, void&gt;::type as constraint it works fine. If I use typename std::enable_if&lt;IsVectorOrList&lt;T&gt;::value&gt;::type the compiler complains:

  1. traits.cpp:32:8: error: invalid use of incomplete type struct conditional&lt;true, IsVector&lt;std::vector&lt;int&gt; &gt;, IsList&lt;std::vector&lt;int&gt; &gt; &gt;’
  2. 32 | struct or_&lt;_B1, _B2&gt; : public conditional&lt;_B1::value, _B1, _B2&gt;::type {};
  3. | ^~~~~~~~~~~~~
  4. traits.cpp:20:8: note: declaration of struct conditional&lt;true, IsVector&lt;std::vector&lt;int&gt; &gt;, IsList&lt;std::vector&lt;int&gt; &gt; &gt;’
  5. 20 | struct conditional;
  6. | ^~~~~~~~~~~

How do I make it work?

答案1

得分: 2

以下是翻译好的部分:

"// taken from libc type_traits" -> "// 从 libc type_traits 中获取"

"The code declares conditional, but that class isn't defined anywhere in the posted snippet." -> "这段代码声明conditional,但该类在发布的片段中没有定义。"

"Removing those lines and using std::conditional the code works." -> "删除这些行并使用 std::conditional 代码可以正常工作。"

英文:

Here:

  1. // taken from libc type_traits
  2. template &lt;bool, typename, typename&gt;
  3. struct conditional;

The code declares conditional, but that class isn't defined anywhere in the posted snippet.

Removing those lines and using std::conditional the code works.

huangapple
  • 本文由 发表于 2023年7月6日 21:01:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76629125.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定