代码之家  ›  专栏  ›  技术社区  ›  v.oddou

要求约束的值必须为bool。所以没有

  •  1
  • v.oddou  · 技术社区  · 6 年前

    我对“原子约束”一章很好奇 https://en.cppreference.com/w/cpp/language/constraints

    它说

    替换后的e类型必须正好是bool。无转换 被允许

    f(0); // error: S<int>{} does not have type bool when checking #1,
              // even though #2 is a better match
    

    哎哟。这意味着 在处理要求条款时没有斯芬纳梅卡尼主义?是不是一个无赖 是吗?
    因为我可以看到一些模板类型如何在遍历表达式后生成bool,而不是其他模板类型。现在我们又需要使用 enable_if 还有东西。痛多了?

    1 回复  |  直到 6 年前
        1
  •  4
  •   Casey    6 年前

    此限制的目的是使错误更难导致不满意或始终满足的概念,例如:

    template<class T> concept C1 = sizeof(T); // Oops, I meant to write sizeof(T) >= 2
    

    如果 sizeof(T) 将隐式转换为 bool , C 会满足所有完整的对象类型。实际上,您可以简单地将表达式强制转换为 布尔 如果这是你真正想要的:

    template<class T> concept C2 = (bool)sizeof(T); // I did *not* mean to write sizeof(T) >= 2
    

    注意,当替换产生无效表达式时,概念是不满足的。( https://godbolt.org/z/xMHoJ0 )以下内容:

    template<class T> concept C3 = (bool)T::value;
    static_assert(C3<std::true_type>);
    static_assert(!C3<int>);
    

    或类型( https://godbolt.org/z/tnreG0 )以下内容:

    template<class T> concept C4 = C3<typename T::type>;
    static_assert(C4<std::is_same<int, int>>);
    static_assert(!C4<int>);
    

    所以“要求条款不适用于sfinae!”不能准确描述情况。

    我想我应该指出另一个潜在的gotcha-原子约束表达式必须是常量表达式。如果替换为约束表达式生成一个非常量表达式,则程序格式错误( https://godbolt.org/z/LQA1XQ ):

    template<class T> concept C5 = T::f();
    
    struct S1 {
        static constexpr bool f() { return true; }
    };
    
    struct S2 {
        static constexpr bool f() { return false; }
    };
    
    struct S3 {
        static bool f() { return true; }
    };
    
    static_assert(!C5<void>); // Invalid expression: SFINAE and concept is not satisfied
    static_assert(!C5<int>);  // Ditto
    
    static_assert(C5<S1>);  // Constant expression that evaluates to true
    static_assert(!C5<S2>); // Constant expression that evaluates to false
    
    static_assert(C5<S3>);  // Ill-formed: not a constant expression