C++20 概念和模板 : fixe-size and resizable array

标签 c++ templates c++20 c++-concepts

我最近开始学习 C++20 中引入的新特性。我在实现概念时遇到了一些麻烦。
玩具示例:
我想定义一个表示可调整大小数组的概念:

template<class T>
concept ResizableArray= std::is_same<std::vector<double>, T>::value;
这样的代码在 Visual Studio 下编译并且运行良好。但是,我一直在写一个表示任何大小的固定大小数组的概念(std::array, std::array ...应该是有效的)。我的尝试:
template<template<unsigned int> class T, unsigned int S>
concept FixedArray = std::is_same<std::array<double, S>, T<double, S>>::value;
不编译!
问题:
  • 错误在哪里?
  • 如何编写表示固定大小数组或可调整大小数组的概念?我的尝试
  • template<template<unsigned int> class T, unsigned int S>
    concept Array= std::is_same<std::vector<double>, T>::value || std::is_same<std::array<double, S>, T<S>>::value;
    
    不编译!
    任何建议,将不胜感激。

    最佳答案

    我认为您以错误的方式处理概念。如果您想要某些类型的强类型标志,模板类特化或常量表达式别名会像过去一样做得很好:

    template<class A>
    struct is_fixed_array : std::false_type {};
    
    // only works with arrays by specialization.
    template<class T, std::size_t I>
    struct is_fixed_array<std::array<T,I>> : std::true_type {};
    
    template<class T>
    constexpr bool is_fixed_array_v = is_fixed_array<T>::value;
    
    相反,使用概念,您希望检查对象接口(interface),而不管您拥有的实际类型如何,并避免像使用 std::is_same<> 那样进行强比较。 .这里有一个小例子说明我的意思:
    template<class T>
    concept ResizableArray = requires(T container)
    {
      // I only accept types that have a method resize(std::size_t)
      container.resize(std::size_t{0});
      // further things that tells you is an array...
    };
    
    template<class T>
    concept FixedArray = requires(T container)
    {
      // I only accept types that are specialized with tuple_size
      std::tuple_size_v<T> -> std::convertible_to<std::size_t>;
      // further things that tells you is an array...
    };
    
    // class with exactly the same interface as array
    template<class T, std::size_t I>
    struct MyArray : std::array<T,I> {};
    
    static_assert(is_fixed_array_v<std::array<int,1>>);
    // static_assert(is_fixed_array_v<MyArray<int,1>>); // assertion fails!
    
    // instead, concepts work with any type that fullfil the defined interface
    static_assert(ResizableArray<std::vector<int>>);
    static_assert(not ResizableArray<MyArray<int,1>>);
    static_assert(not FixedArray<std::vector<int>>);
    static_assert(FixedArray<MyArray<int,1>>);
    

    关于C++20 概念和模板 : fixe-size and resizable array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62940931/

    相关文章:

    c++ - uniform_real_distribution 不统一

    c++ - 在基类指针容器中访问派生类对象的正确方法是什么?

    c++ - 在 std::function 中使用模板参数

    c++ - 如何在编译时初始化一个 float 组?

    c++ - 如何为 UWP C++/WinRT 应用程序创建 "suitable await_ready function"?

    c++ - 将 std::atomic 与 futex 系统调用一起使用

    c++ - 使用基于编译器的 cmake 条件 CXX_FLAGS?

    c++ - 如何在不导致像素重叠的情况下缩小块

    c++ - C++ 中的回调,模板成员? (2)

    c++ - 基数或 [[no_unique_address]] 成员的填充是否可用于存储其他基数/成员?