概念检查的显式实例化

时间:2017-02-18 22:01:36

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

我们有:

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,但是编译器抱怨它是错误的命名空间。我该如何解决这个问题?

2 个答案:

答案 0 :(得分: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");
};

答案 1 :(得分:0)

所以,我找到了一个有效的例子:

#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