【问题标题】:The syntax of a concept in C++20C++20 中概念的语法
【发布时间】:2021-07-12 05:51:45
【问题描述】:

我们如何将这个问题link中的要求转换为概念

我尝试了以下方法:

template< typename U, typename Tin, typename Tout>
concept MyConditions =
    (
         U::value_type
        &&  Tin::value_type
        &&  Tout::value_type
        && std::is_floating_point_v<typename Tin::value_type>
        && std::is_integral_v<typename U::value_type>
        && std::is_floating_point_v<typename Tout::value_type>
    );

这个概念现在应用于我的一个成员函数:

class test_concept
{
template< typename U, typename Tin, typename Tout>
requires MyConditions <U, Tin, Tout>
static void test_routine(const U&, const Tin&, Tout& );
}

测试时:

std::vector<double> test{ };
std::vector<int> testi{ };
std::vector<double> test2{ };

test_concept::test_routine(testi, test, test2);

使用 clang 我收到错误消息,指出未找到匹配项,并附注:

注意:因为替换的约束表达式格式不正确:缺失 'typename' 之前 依赖类型名称 'vector::value_type' U::value_type

【问题讨论】:

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


    【解决方案1】:

    您无需手动检查类型是否存在。如果它们不存在,SFINAE 将导致您的概念以静默方式返回false。所以:

    template< typename U, typename Tin, typename Tout>
    concept MyConditions =
        std::is_integral_v<typename T::value_type> &&
        std::is_floating_point_v<typename U::value_type> &&
        std::is_floating_point_v<typename Tout::value_type>;
    

    但如果你想显式检查类型,语法如下:

    template< typename U, typename Tin, typename Tout>
    concept MyConditions =
        requires
        {
            typename U::value_type;
            typename Tin::value_type;
            typename Tout::value_type;
        } &&
        std::is_integral_v<typename T::value_type> &&
        std::is_floating_point_v<typename U::value_type> &&
        std::is_floating_point_v<typename Tout::value_type>;
    

    您还可以将所有条件移入requires

    template< typename U, typename Tin, typename Tout>
    concept MyConditions =
        requires
        {
            typename U::value_type;
            typename Tin::value_type;
            typename Tout::value_type;
            requires std::is_integral_v<typename T::value_type>;
            requires std::is_floating_point_v<typename U::value_type>;
            requires std::is_floating_point_v<typename Tout::value_type>;
        };
    

    此外,您应该更喜欢标准概念而不是旧特征:

    template< typename U, typename Tin, typename Tout>
    concept MyConditions =
        requires
        {
            typename U::value_type;
            typename Tin::value_type;
            typename Tout::value_type;
            requires std::integral<typename T::value_type>;
            requires std::floating_point<typename U::value_type>;
            requires std::floating_point<typename Tout::value_type>;
        };
    

    【讨论】:

    • 感谢您提供不同的选项!。更喜欢标准概念是什么意思?我们应该更喜欢std::integral&lt;typename T::value_type&gt; 而不是std::integral_v&lt;typename T::value_type&gt; 吗?如果是,那为什么?
    • @A2LBK 是的,我就是这个意思。我认为这在这里没有什么不同,但在某些情况下确实如此。见stackoverflow.com/questions/52062386/…
    • 虽然您可以将所有条件移动到requires,但盲目地这样做并不是一个好主意,因为它会将您的概念从公认的原子约束结合变成一个大块。从问题中提取概念,这意味着 MyConditions 不再比其任何 std::integral/floating_point 片段更具体,因此您不能再用 std::integral&lt;typename T::value_type&gt; 函数重载 MyConditions&lt;T, ...&gt; 函数并让重载解析起作用正如你所料。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-06
    • 1970-01-01
    • 2020-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多