Pointer to class member as template parameter
From the standard:
A non-type template-parameter shall have one of the following (optionally cv-qualified) types:
- integral or enumeration type,
- pointer to object or pointer to function,
- reference to object or reference to function,
- pointer to member.
So it is allowed, and seems to work on g++
like this:
template <Dog Person::*ptr>
struct Strange { ... };
Passing a pointer-to-class-member as a template parameter
You can't do just test<&AA::type>
, since you'd need to also tell the function template what type of pointer-to-member you're expecting. The typical pattern is:
template <class M, M member, class T> // deduced go last
void test(T& a) {
cout << (a.*member);
}
With usage:
test<decltype(&AA::type), &AA::type>
I believe there's currently a proposal to reduce the verbosity there, but until then, it's not the worst thing in the world, and you could always:
#define TYPE_AND_VAL(foo) decltype(foo), foo
test<TYPE_AND_VAL(&AA::type)>
That proposal I mentioned is in C++17, and will allow you to do:
template <auto member, class T>
void test(T& a) {
cout << (a.*member);
}
test<&AA::type>(a);
Pointer to class member as a template parameter
In c++17, with the addition of auto
in template arguments (P0127), I think you can now do:
template<auto value>
struct MyStruct {};
template<typename Class, typename Result, Result Class::* value>
struct MyStruct<value> {
// add members using Class, Result, and value here
using containing_type = Class;
};
typename MyStruct<&Something::theotherthing>::containing_type x = Something();
Passing member function pointer as template parameter
template<typename F>
void call_func(F func) {
(wrapped.*func)();
}
then call like this:
wr.call_func(&some_class::some_func);
If you want to use the return value too, you'll need this:
template<typename F>
auto call_func(F func) -> decltype((std::declval<T>().*func)()) {
return (wrapped.*func)();
}
If you have C++14, you can omit the -> decltype(...)
part and use decltype(auto)
as the return value.
If you also want to pass functions, you can use variadic templates and forwarding for that.
template<typename F, typename... Args>
decltype(auto) call_func(F func, Args&&... args) {
return (wrapped.*func)(std::forward<Args>(args)...);
}
Deducing pointer-to-member template arguments
With C++17 you can use auto
non-type template parameter:
template<auto p_member>
struct Magic
{ };
Before C++17 only the longer variant that you've implemented would work.
Inferring type and class when passing a pointer to data member as a non-type template argument
You can use a helper to get the type of the class and the member from the type of a member pointer:
template <typename T> struct type_from_member;
template <typename Cls,typename M>
struct type_from_member<M Cls::*> {
using class_type = Cls;
using member_type = M;
};
Then you can use auto
and inherit from the helper:
template <auto member> struct Mem : type_from_member<decltype(member)> {};
using B = Mem<&Struct::x>;
static_assert( std::is_same_v<B::member_type,int>);
static_assert( std::is_same_v<B::class_type,Struct>);
Pointers to member as variadic template parameters
In C++14, you can use another level of indirection to do that:
struct A {
int a;
float b;
};
template<typename... T>
struct Bar {
template <T A::*... params>
struct Foo {
void Bar(A *obj) {
void *members[] { (&(obj->*params))... };
// ... do something ...
(void)members;
}
};
};
int main() {
A a;
Bar<int, float>::Foo<&A::a, &A::b> foo;
foo.Bar(&a);
}
auto
keyword (introduced with the C++17 for non-type template parameters, as you mentioned) solves more or less this kind of issues. Think of std::integral_constant
and how would it be more user-friendly if you hadn't to specify each time the type as the first argument...
Related Topics
Openmp and Reduction on Std::Vector
Understanding Y Combinator Through Generic Lambdas
Unordered_Map Constructor Error (Equal_To Templated Function)
How to Create a Temporary Text File in C++
Cancel Async_Read Due to Timeout
Objects of Different Classes in a Single Vector
Determine How Many Times File Is Mapped into Memory
Boost Spirit X3: Parse into Structs
Cannot Evaluate Function -- May Be Inlined
Math Interface VS Cmath in C++
Emplace an Aggregate in Std::Vector
Access Violation Writing Location 0Xcccccccc
Array[Byte] to Hbitmap or Cbitmap
What Happens When Calling the Destructor of a Thread Object That Has a Condition Variable Waiting
How to Analyze Program Running Time