【问题标题】:Explicit instantiation for concept checking概念检查的显式实例化
【发布时间】:2017-02-18 22:01:35
【问题描述】:

我们有:

template<typename T>
struct A {
  void foo(int a) {
    T::foo(a);
  }
};

template<typename T> 
struct B {
  template struct A<T>; // concept check
};

所以,我定义了一个概念检查器 A,它通过将 foo 转发到 T::foo 来检查 T。

现在,我想通过显式实例化检查传递给 B 的参数是否满足概念 A,但编译器抱怨它是错误的命名空间。我该如何解决?

【问题讨论】:

  • A 不是一个概念。这是一个struct。即使使用 Concepts TS,它仍然是一个结构;在概念 TS 中,概念是函数或变量。所以你的问题似乎很困惑。
  • 好吧,忽略混乱。如何申请支票?
  • 应用什么检查?如前所述,A 不检查任何内容
  • 编译器应该抱怨 T::foo 不存在,例如如果 B 是用空结构实例化的。
  • A::foo 在 odr 使用(调用,或获取其地址)之前不会被实例化。只有这样编译器才会验证表达式T::foo(a); 是否有意义。我想您可以创建一个将函数指针作为非类型模板参数的模板,并使用&amp;A&lt;T&gt;::foo 对其进行实例化。

标签: c++ c++11 c++-concepts


【解决方案1】:

可能是这样的:

template<typename T, void(T::*)(int)>
struct A {};

template<typename T> 
struct B {
  using Check = A<T, &T::foo>;
};

Demo


或者这个:

template<typename T> 
struct B {
  static_assert(
    std::is_same<decltype(&T::foo), void(T::*)(int)>::value,
    "No T::foo(int) member");
};

【讨论】:

    【解决方案2】:

    所以,我找到了一个可行的例子:

    #include <tuple>
    
    template<typename A>
    struct IA : A {
        void foo(int a) {
            A::foo(a);
        }
    
        void bar(double a) {
            A::bar(a);
        }  
    
        static constexpr auto $ = std::make_tuple(&IA::foo, &IA::bar);
    };
    
    template<typename T> 
    struct B {
        // trigger concept/interface check of T "implements" IA
        static constexpr auto $ = IA<T>::$;
    };
    
    struct Test {
        void foo(int a) {}
        void bar(int a, int b) {}
    };
    
    int main() {
        B<Test> b;
        b = b;
    }
    

    结构中 $ 的生成会触发编译。上面示例中的编译器正确地抱怨:

     In instantiation of 'void IA<A>::bar(double) [with A = Test]':
    13:57:   required from 'constexpr const std::tuple<void (IA<Test>::*)(int), void (IA<Test>::*)(double)> IA<Test>::$'
    18:27:   recursively required from 'constexpr const std::tuple<void (IA<Test>::*)(int), void (IA<Test>::*)(double)> B<Test>::$'
    18:27:   required from 'struct B<Test>'
    28:13:   required from here
    10:17: error: no matching function for call to 'IA<Test>::bar(double&)'
    10:17: note: candidate is:
    24:10: note: void Test::bar(int, int)
    24:10: note:   candidate expects 2 arguments, 1 provided
    

    【讨论】:

    • 名为 $ 的变量不是合法的 C++。
    • 有人可以更改上面的示例,使其不需要创建全局“静态”吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-10
    • 1970-01-01
    • 2021-12-24
    • 2020-11-29
    • 2021-11-27
    • 2022-01-18
    相关资源
    最近更新 更多