非类型成员函数指针值的部分模板专用化



我想为非类型模板参数专门化一个结构,特别是为编译时已知的成员函数指针。作为一个例子,我从int和非int值开始,它可以很好地工作并打印

false true

但是当我取消注释adap时,我得到以下编译错误

callable.cc:9:39: error: template argument 1 is invalid
9 | struct adap<Ret(Class::*Fptr)(Args...)> : std::false_type {};
#include <functional>
#include <iostream>
using namespace std;
/* Comment out
template <auto T>
struct adap : std::true_type {};
template <typename Ret, typename Class, typename ...Args>
struct adap<Ret(Class::*Fptr)(Args...)> : std::false_type {};
*/
template <auto T>
struct A {
static constexpr bool value = true;
};
template <int N>
struct A<N> {
static constexpr bool value = false;
};
struct B {
void f() {
}
};
int main() {
std::cout << boolalpha << A<4>::value << " " << A<char{'a'}>::value << endl;
//   adap<&B::f> ad;
}

为模板创建部分专用化时,必须向主专用化提供模板参数,以指示何时应使用部分专用化。adap的主模板采用非类型模板参数:一个值。所以你的部分专业化需要提供价值。

但事实并非如此。Fptr不是一个值。我猜你打算把它作为一个参数的名称。但你没有提供一个参数;您提供了一个参数,该参数符合主模板中定义的相应模板参数。该参数是NTTP,必须提供。其理念是,当用户提供该价值时,您的专业化将接管。

添加了auto推导的NTTP参数,这样就可以避免执行类似的操作:template<typename T, T value>。你的专业化基本上需要把它带回来。模板头应该采用成员指针的组件类型(返回类型、类类型和参数(NTTP值,NTTP值是使用这些组件的成员指针类型。然后将该值传递给主模板:

template <auto T>
struct adap : std::true_type {};
template <typename Ret, typename Class, typename ...Args, Ret(Class::*value)(Args...)>
struct adap<value> : std::false_type {};

最新更新