I would like to partially specialize a structure for a non-type template parameter, specifically for member function pointers known at compile time. As an example, I start with int
and non int
values and that works fine and prints
false true
but when I un-comment adap
, I get the following compile error
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;
}
When you create a partial specialization for a template, you have to provide template argument(s) to the primary specialization that signal when your partial specialization should be used. The primary template for adap
takes a non-type template parameter: a value. So your partial specialization needs to provide a value.
Which it doesn't. Fptr
is not a value. I'm guessing that you intend it to be the name of a parameter. But you're not providing a parameter; you're providing an argument , one that fits the corresponding template parameter defined in the primary template. That parameter being an NTTP, you must provide a value . The idea being that when a user provides that value, your specialization will take over.
auto
-deduced NTTP parameters were added so that you could avoid having to do something like this: template<typename T, T value>
. Your specialization needs to basically bring this back. Your template header should take the component types of a member pointer (return type, class type, and arguments) and an NTTP value which is a member pointer type that uses these components. You then pass that value to the primary template:
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 {};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.