代码之家  ›  专栏  ›  技术社区  ›  Alessandro Muntoni

具有依赖参数类型的概念约束成员函数

  •  2
  • Alessandro Muntoni  · 技术社区  · 3 年前

    我用概念做了一些实验,我试图得到约束成员函数,只有在满足概念的情况下才能实例化这些函数:

    template <typename T>
    concept Fooable = requires(T o)
    {
        o.foo(uint());
    };
    
    template <typename T>
    concept Barable = requires(T o)
    {
        o.bar(uint());
    };
    
    class Foo
    {
    public:
        using FooType = int;
        void foo(uint) {}
    };
    
    class Bar
    {
    public:
        using BarType = double;
        void bar(uint) {}
    };
    
    template <typename T>
    class C
    {
    public:
        void fun(typename T::FooType t) requires Fooable<T> {}
        void fun(typename T::BarType t) requires Barable<T> {}
    };
    
    int main()
    {
        C<Foo> f;
    }
    

    main.cpp: error: no type named 'BarType' in 'Foo'
    main.cpp: error: no type named 'BarType' in 'Foo'
            void fun(typename T::BarType t) requires Barable<T> {}
                     ~~~~~~~~~~~~^~~~~~~
    main.cpp: note: in instantiation of template class 'C<Foo>' requested here
            C<Foo> f;
                   ^
    

    然而,由于我宣布 C 具有的对象 Foo fun 具有 BarType 不会实例化。

    1 回复  |  直到 3 年前
        1
  •  3
  •   康桓瑋    3 年前

    自从 fun 不是模板函数, typename T::BarType T 没有名为的类型别名 BarType .你可能想做

    template <typename T>
    class C
    {
    public:
        template<Fooable U = T>
          requires requires { typename U::FooType; }
        void fun(typename U::FooType t);
        template<Barable U = T>
          requires requires { typename U::BarType; }
        void fun(typename U::BarType t);
    };
    

    鉴于此 Barable ,更合适的方法是将您的概念重新定义为(I代替 uint() 具有 0U 因为没有所谓的 uint

    template<typename T>
    concept Fooable = requires(T o) {
      o.foo(0U);
      typename T::FooType;
    };
    
    template<typename T>
    concept Barable = requires(T o) {
      o.bar(0U);
      typename T::BarType;
    };
    
    template <typename T>
    class C {
      public:
        template<Fooable F = T>
        void fun(typename F::FooType t);
        template<Barable B = T>
        void fun(typename B::BarType t);
    };
    

    这要求类型满足 必须具有名为的类型别名 BarType公司 .