【问题标题】:How to express concepts over variadic template?如何通过可变参数模板表达概念?
【发布时间】:2021-02-17 23:35:20
【问题描述】:

我想定义一个概念,只有具有特定类型值的元组才能满足。

为了简单起见,我只想接受只包含数字类型元素的元组。我该怎么做?

例如

std::tuple<int16_t, int32_t> // satisfies concept
std::tuple<std::string, double> // doesn't satisfy concept

问题是我必须制定类似“for_each_type”的内容。也不允许使用递归概念。

【问题讨论】:

    标签: c++ tuples variadic-templates c++20 c++-concepts


    【解决方案1】:

    很简单:

    namespace impl {
        template <class T>
        struct is_tuple_of_integrals
        : std::false_type { };
        
        template <std::integral... Ts>
        struct is_tuple_of_integrals<std::tuple<Ts...>>
        : std::true_type { };
    }
    
    template <class T>
    concept tuple_of_integrals = impl::is_tuple_of_integrals<T>::value;
    

    我确实想知道是否可以省略中间特征,但我不相信没有概念专业化。

    【讨论】:

    • 听说你喜欢概念。所以我在你的概念里放了一个概念,这样你就可以在检查约束的同时检查约束:)
    • @StoryTeller-UnslanderMonica 一直是概念!
    • 我的意思是当然 sfinae 是一个选项(因此我赞成),但我仍然会对仅使用概念的解决方案感兴趣。或者,如果这不可能是一个原因,因为目前关于 SO 的概念很少有问题,这使得初学者很难学习。
    • @user3520616 这里没有 SFINAE,只有部​​分专业化。如前所述,我相信我们在某个点需要一个来获取元组元素,并且概念不能部分专门化,因此我们需要介于两者之间的其他东西。
    • @user3520616 好吧,第一个概念只能用类型列表直接调用。第二个 sn-p 定义了一个函数模板,而不是一个概念——尽管您确实可以在 decltype 中使用重载的函数模板来执行模式匹配而不是类模板。
    【解决方案2】:

    我的解决方案:

    template<typename ... Args>
    concept numeric_tuples = (std::is_integral_v<Args> && ...);
    
    template<typename ... Args>
    void foo(std::tuple<Args...> t) requires numeric_tuples<Args...> {
    
    }
    

    这个概念我使用了折叠表达式。

    【讨论】:

    • 或者更简洁的变体:template &lt;std::integral... Ts&gt; void foo(std::tuple&lt;Ts...&gt;) { }
    • @Quentin 是的,你的解决方案更好。
    猜你喜欢
    • 2019-11-23
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多