Constrain function argument to allocators using C++20 concepts

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

Constrain function argument to allocators using C++20 concepts

问题

以下是您要翻译的代码部分:

  1. 我想要限制构造函数只接受分配器作为参数,并且我提出了这个概念:
  2. #include <iostream>
  3. #include <string>
  4. #include <memory>
  5. #include <memory_resource>
  6. #include <vector>
  7. #include <concepts>
  8. #include <utility> /* declval */
  9. template <typename Allocator>
  10. concept is_allocator = requires(Allocator a) {
  11. typename Allocator::value_type;
  12. { a.allocate(std::declval<std::size_t>()) } -> std::same_as<typename Allocator::value_type*>;
  13. { a.deallocate(std::declval<typename Allocator::value_type>(), std::declval<std::size_t>()) } -> std::same_as<void>;
  14. };
  15. template <typename T>
  16. struct MyAllocator {
  17. using value_type = T;
  18. auto allocate(std::size_t size) -> T*;
  19. auto deallocate(T*, std::size_t size) -> void;
  20. };
  21. int main() {
  22. using A1 = std::allocator<int>;
  23. using A2 = std::pmr::polymorphic_allocator<std::byte>;
  24. using B = MyAllocator<int>;
  25. using C = std::string;
  26. if constexpr(is_allocator<A1>) {
  27. std::cout << "A1 is an allocator" << std::endl;
  28. }
  29. if constexpr(is_allocator<A2>) {
  30. std::cout << "A2 is an allocator" << std::endl;
  31. }
  32. if constexpr(is_allocator<B>) {
  33. std::cout << "B is an allocator" << std::endl;
  34. }
  35. if constexpr(is_allocator<C>) {
  36. std::cout << "C is an allocator" << std::endl;
  37. }
  38. }

我将代码部分翻译好了,没有包含其他内容。

英文:

I wanted to constrain a constructor to take only allocators as arguments and I came up with this concept:

Demo

  1. #include &lt;iostream&gt;
  2. #include &lt;string&gt;
  3. #include &lt;memory&gt;
  4. #include &lt;memory_resource&gt;
  5. #include &lt;vector&gt;
  6. #include &lt;concepts&gt;
  7. #include &lt;utility&gt; /* declval */
  8. template &lt;typename Allocator&gt;
  9. concept is_allocator = requires(Allocator a) {
  10. typename Allocator::value_type;
  11. { a.allocate(std::declval&lt;std::size_t&gt;()) } -&gt; std::same_as&lt;typename Allocator::value_type*&gt;;
  12. { a.deallocate(std::declval&lt;typename Allocator::value_type&gt;(), std::declval&lt;std::size_t&gt;()) } -&gt; std::same_as&lt;void&gt;;
  13. };
  14. template &lt;typename T&gt;
  15. struct MyAllocator {
  16. using value_type = T;
  17. auto allocate(std::size_t size) -&gt; T*;
  18. auto deallocate(T*, std::size_t size) -&gt; void;
  19. };
  20. int main() {
  21. using A1 = std::allocator&lt;int&gt;;
  22. using A2 = std::pmr::polymorphic_allocator&lt;std::byte&gt;;
  23. using B = MyAllocator&lt;int&gt;;
  24. using C = std::string;
  25. if constexpr(is_allocator&lt;A1&gt;) {
  26. std::cout &lt;&lt; &quot;A1 is an allocator&quot; &lt;&lt; std::endl;
  27. }
  28. if constexpr(is_allocator&lt;A2&gt;) {
  29. std::cout &lt;&lt; &quot;A2 is an allocator&quot; &lt;&lt; std::endl;
  30. }
  31. if constexpr(is_allocator&lt;B&gt;) {
  32. std::cout &lt;&lt; &quot;B is an allocator&quot; &lt;&lt; std::endl;
  33. }
  34. if constexpr(is_allocator&lt;C&gt;) {
  35. std::cout &lt;&lt; &quot;C is an allocator&quot; &lt;&lt; std::endl;
  36. }
  37. }

I expected it to detect allocators in A1, A2, B and C case but it doesn't detect a single allocator. Why does this concept not hold true?

答案1

得分: 2

My bad, forgot a '*'... Here's the corrected version that works correctly (credits to @康桓瑋 for more conciseness)!

Demo

  1. #include <iostream>
  2. #include <string>
  3. #include <memory>
  4. #include <memory_resource>
  5. #include <vector>
  6. #include <concepts>
  7. template <typename Allocator>
  8. concept is_allocator = requires(Allocator a, typename Allocator::value_type* p) {
  9. { a.allocate(0) } -> std::same_as<decltype(p)>;
  10. { a.deallocate(p, 0) } -> std::same_as<void>;
  11. };
  12. template <typename T>
  13. struct MyAllocator {
  14. using value_type = T;
  15. auto allocate(std::size_t size) -> T*;
  16. auto deallocate(T*, std::size_t size) -> void;
  17. };
  18. int main() {
  19. using A1 = std::allocator<int>;
  20. using A2 = std::pmr::polymorphic_allocator<std::byte>;
  21. using B = MyAllocator<int>;
  22. using C = std::string;
  23. if constexpr(is_allocator<A1>) {
  24. std::cout << "A1 is an allocator" << std::endl;
  25. }
  26. if constexpr(is_allocator<A2>) {
  27. std::cout << "A2 is an allocator" << std::endl;
  28. }
  29. if constexpr(is_allocator<B>) {
  30. std::cout << "B is an allocator" << std::endl;
  31. }
  32. if constexpr(is_allocator<C>) {
  33. std::cout << "C is an allocator" << std::endl;
  34. }
  35. }
英文:

My bad, forgot a '*'... Here's the corrected version that works correctly (credits to @康桓瑋 for more conciseness)!

Demo

  1. #include &lt;iostream&gt;
  2. #include &lt;string&gt;
  3. #include &lt;memory&gt;
  4. #include &lt;memory_resource&gt;
  5. #include &lt;vector&gt;
  6. #include &lt;concepts&gt;
  7. template &lt;typename Allocator&gt;
  8. concept is_allocator = requires(Allocator a, typename Allocator::value_type* p) {
  9. { a.allocate(0) } -&gt; std::same_as&lt;decltype(p)&gt;;
  10. { a.deallocate(p, 0) } -&gt; std::same_as&lt;void&gt;;
  11. };
  12. template &lt;typename T&gt;
  13. struct MyAllocator {
  14. using value_type = T;
  15. auto allocate(std::size_t size) -&gt; T*;
  16. auto deallocate(T*, std::size_t size) -&gt; void;
  17. };
  18. int main() {
  19. using A1 = std::allocator&lt;int&gt;;
  20. using A2 = std::pmr::polymorphic_allocator&lt;std::byte&gt;;
  21. using B = MyAllocator&lt;int&gt;;
  22. using C = std::string;
  23. if constexpr(is_allocator&lt;A1&gt;) {
  24. std::cout &lt;&lt; &quot;A1 is an allocator&quot; &lt;&lt; std::endl;
  25. }
  26. if constexpr(is_allocator&lt;A2&gt;) {
  27. std::cout &lt;&lt; &quot;A2 is an allocator&quot; &lt;&lt; std::endl;
  28. }
  29. if constexpr(is_allocator&lt;B&gt;) {
  30. std::cout &lt;&lt; &quot;B is an allocator&quot; &lt;&lt; std::endl;
  31. }
  32. if constexpr(is_allocator&lt;C&gt;) {
  33. std::cout &lt;&lt; &quot;C is an allocator&quot; &lt;&lt; std::endl;
  34. }
  35. }

huangapple
  • 本文由 发表于 2023年6月29日 23:08:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76582347.html
匿名

发表评论

匿名网友

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

确定