如何解决通过概念检查模板化静态方法
我想写一个概念来检查该类型是否有一个名为 foo
的静态方法。该方法将有一个模板化参数(该函数将使用不同的参数类型多次调用)。
由于模板化参数的存在,检查起来非常困难。一开始,我以为我只检查是否有使用该名称的成员。
以下代码用 Clang 编译,但不能用 GCC 编译,因为它无法解析重载函数 T::foo
的地址。
template <typename T>
concept HasFoo = requires { T::foo; };
class Bar {
public:
template <typename T>
static void foo(T t);
};
static_assert(HasFoo<Bar>);
您如何正确检查模板化静态方法的存在(在 Clang 和 GCC 中工作)?
理想情况下,您甚至可以检查更多吗?比如检查返回类型是否为 void
,或者是否可以调用。
一种方法是将模板类型包含在概念中,但因为我想使用具有多种不同类型的方法。 因此,仅检查一种类型(如以下代码)是不够的。
template <typename T,typename T2>
concept HasFoo = requires { T::template foo<T2>; };
static_assert(HasFoo<Bar,int>);
解决方法
您如何正确检查模板化静态方法的存在(在 Clang 和 GCC 中工作)?理想情况下,您甚至可以检查更多吗?比如检查返回类型是否为空,或者是否可以调用。
我确实对模板参数有一些限制,为了问题中的简化示例,我们可以假设它是整数类型。
要检查该类是否支持可使用整数调用并返回 foo()
的静态模板方法 void
,您可以简单地检查
template <typename T>
concept HasFoo = std::is_same_v<decltype(T::foo(0)),void>;
如果您还想确保 foo()
方法是模板方法,我想您还可以检查将 &T::foo
转换为不同的函数指针类型会得到不同的值,因此(例如)
( (void*)(&T::template foo<int>)
!= (void*)(&T::template foo<long>))
结合这两个要求,
template <typename T>
concept HasFoo = ( (void*)(&T::template foo<int>)
!= (void*)(&T::template foo<long>))
&& std::is_same_v<decltype(T::foo(0)),void>;
与
struct Bar1
{ template <typename T> static void foo (T) {} };
struct Bar2
{ static void foo (int) {} };
struct Bar3
{ template <typename T> static T foo; };
template <typename T>
T Bar3::foo;
struct Bar4
{ template <typename T> static int foo (T) { return 0; } };
你有
static_assert(HasFoo<Bar1>);
static_assert(not HasFoo<Bar2>); // not because foo() isn't template
static_assert(not HasFoo<Bar3>); // not because foo isn't callable
static_assert(not HasFoo<Bar4>); // not becasue foo() return int
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。