英文:
Constrain function argument to allocators using C++20 concepts
问题
以下是您要翻译的代码部分:
我想要限制构造函数只接受分配器作为参数,并且我提出了这个概念:
#include <iostream>
#include <string>
#include <memory>
#include <memory_resource>
#include <vector>
#include <concepts>
#include <utility> /* declval */
template <typename Allocator>
concept is_allocator = requires(Allocator a) {
typename Allocator::value_type;
{ a.allocate(std::declval<std::size_t>()) } -> std::same_as<typename Allocator::value_type*>;
{ a.deallocate(std::declval<typename Allocator::value_type>(), std::declval<std::size_t>()) } -> std::same_as<void>;
};
template <typename T>
struct MyAllocator {
using value_type = T;
auto allocate(std::size_t size) -> T*;
auto deallocate(T*, std::size_t size) -> void;
};
int main() {
using A1 = std::allocator<int>;
using A2 = std::pmr::polymorphic_allocator<std::byte>;
using B = MyAllocator<int>;
using C = std::string;
if constexpr(is_allocator<A1>) {
std::cout << "A1 is an allocator" << std::endl;
}
if constexpr(is_allocator<A2>) {
std::cout << "A2 is an allocator" << std::endl;
}
if constexpr(is_allocator<B>) {
std::cout << "B is an allocator" << std::endl;
}
if constexpr(is_allocator<C>) {
std::cout << "C is an allocator" << std::endl;
}
}
我将代码部分翻译好了,没有包含其他内容。
英文:
I wanted to constrain a constructor to take only allocators as arguments and I came up with this concept:
#include <iostream>
#include <string>
#include <memory>
#include <memory_resource>
#include <vector>
#include <concepts>
#include <utility> /* declval */
template <typename Allocator>
concept is_allocator = requires(Allocator a) {
typename Allocator::value_type;
{ a.allocate(std::declval<std::size_t>()) } -> std::same_as<typename Allocator::value_type*>;
{ a.deallocate(std::declval<typename Allocator::value_type>(), std::declval<std::size_t>()) } -> std::same_as<void>;
};
template <typename T>
struct MyAllocator {
using value_type = T;
auto allocate(std::size_t size) -> T*;
auto deallocate(T*, std::size_t size) -> void;
};
int main() {
using A1 = std::allocator<int>;
using A2 = std::pmr::polymorphic_allocator<std::byte>;
using B = MyAllocator<int>;
using C = std::string;
if constexpr(is_allocator<A1>) {
std::cout << "A1 is an allocator" << std::endl;
}
if constexpr(is_allocator<A2>) {
std::cout << "A2 is an allocator" << std::endl;
}
if constexpr(is_allocator<B>) {
std::cout << "B is an allocator" << std::endl;
}
if constexpr(is_allocator<C>) {
std::cout << "C is an allocator" << std::endl;
}
}
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)!
#include <iostream>
#include <string>
#include <memory>
#include <memory_resource>
#include <vector>
#include <concepts>
template <typename Allocator>
concept is_allocator = requires(Allocator a, typename Allocator::value_type* p) {
{ a.allocate(0) } -> std::same_as<decltype(p)>;
{ a.deallocate(p, 0) } -> std::same_as<void>;
};
template <typename T>
struct MyAllocator {
using value_type = T;
auto allocate(std::size_t size) -> T*;
auto deallocate(T*, std::size_t size) -> void;
};
int main() {
using A1 = std::allocator<int>;
using A2 = std::pmr::polymorphic_allocator<std::byte>;
using B = MyAllocator<int>;
using C = std::string;
if constexpr(is_allocator<A1>) {
std::cout << "A1 is an allocator" << std::endl;
}
if constexpr(is_allocator<A2>) {
std::cout << "A2 is an allocator" << std::endl;
}
if constexpr(is_allocator<B>) {
std::cout << "B is an allocator" << std::endl;
}
if constexpr(is_allocator<C>) {
std::cout << "C is an allocator" << std::endl;
}
}
英文:
My bad, forgot a '*'... Here's the corrected version that works correctly (credits to @康桓瑋 for more conciseness)!
#include <iostream>
#include <string>
#include <memory>
#include <memory_resource>
#include <vector>
#include <concepts>
template <typename Allocator>
concept is_allocator = requires(Allocator a, typename Allocator::value_type* p) {
{ a.allocate(0) } -> std::same_as<decltype(p)>;
{ a.deallocate(p, 0) } -> std::same_as<void>;
};
template <typename T>
struct MyAllocator {
using value_type = T;
auto allocate(std::size_t size) -> T*;
auto deallocate(T*, std::size_t size) -> void;
};
int main() {
using A1 = std::allocator<int>;
using A2 = std::pmr::polymorphic_allocator<std::byte>;
using B = MyAllocator<int>;
using C = std::string;
if constexpr(is_allocator<A1>) {
std::cout << "A1 is an allocator" << std::endl;
}
if constexpr(is_allocator<A2>) {
std::cout << "A2 is an allocator" << std::endl;
}
if constexpr(is_allocator<B>) {
std::cout << "B is an allocator" << std::endl;
}
if constexpr(is_allocator<C>) {
std::cout << "C is an allocator" << std::endl;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论