用于概念检查的显式实例化
Explicit instantiation for concept checking
我们有:
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,但编译器抱怨它是错误的命名空间。我该如何解决?
也许是这样的:
template<typename T, void(T::*)(int)>
struct A {};
template<typename T>
struct B {
using Check = A<T, &T::foo>;
};
或者这样:
template<typename T>
struct B {
static_assert(
std::is_same<decltype(&T::foo), void(T::*)(int)>::value,
"No T::foo(int) member");
};
所以,我找到了一个工作示例:
#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;
}
structs中$的生成触发编译。上面示例中的编译器正确地抱怨:
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
我们有:
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,但编译器抱怨它是错误的命名空间。我该如何解决?
也许是这样的:
template<typename T, void(T::*)(int)>
struct A {};
template<typename T>
struct B {
using Check = A<T, &T::foo>;
};
或者这样:
template<typename T>
struct B {
static_assert(
std::is_same<decltype(&T::foo), void(T::*)(int)>::value,
"No T::foo(int) member");
};
所以,我找到了一个工作示例:
#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;
}
structs中$的生成触发编译。上面示例中的编译器正确地抱怨:
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