使用C++20概念将函数参数约束到分配器

zwghvu4y  于 2023-07-01  发布在  其他
关注(0)|答案(1)|浏览(118)

我想限制构造函数只接受分配器作为参数,我提出了这个概念:
演示

#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;
    }
}

我希望它能检测A1、A2、B和C情况下的分配器,但它没有检测到单个分配器。为什么这个概念不成立?

bz4sfanl

bz4sfanl1#

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;
    }
}

相关问题