Can I get the Owning Object of a Member Function Template Parameter?
Clash Royale CLAN TAG#URR8PPP
up vote
7
down vote
favorite
Given a object:
struct foo
void func();
;
Now given the templatized function declaration:
template<typename T, T F>
void bar();
So bar
will be taking in a member function like so:
bar<decltype(&foo::func), &foo::func>()
In the body of bar
I want to recover the type foo
from T
. Can I do that? I want to be able to do something like this:
get_obj<T> myfoo;
(myfoo.*F)();
I know that get_obj
isn't a thing, but would there be a way to write it?
c++ templates methods member-function-pointers metatype
add a comment |Â
up vote
7
down vote
favorite
Given a object:
struct foo
void func();
;
Now given the templatized function declaration:
template<typename T, T F>
void bar();
So bar
will be taking in a member function like so:
bar<decltype(&foo::func), &foo::func>()
In the body of bar
I want to recover the type foo
from T
. Can I do that? I want to be able to do something like this:
get_obj<T> myfoo;
(myfoo.*F)();
I know that get_obj
isn't a thing, but would there be a way to write it?
c++ templates methods member-function-pointers metatype
I figured I should mention that I do know that I can simplifybar
totemplate<auto F> void bar()
This just seemed simpler to write it this way.
â Jonathan Mee
4 hours ago
"something like this" do you mean to domyfoo.*F
instead offoo.*F
? And it appears you want to find the object type that a given member function is for, not the actual object?
â Yakk - Adam Nevraumont
4 hours ago
@Yakk-AdamNevraumont Yes you're right. I'm failing at freehanding code today :(
â Jonathan Mee
4 hours ago
add a comment |Â
up vote
7
down vote
favorite
up vote
7
down vote
favorite
Given a object:
struct foo
void func();
;
Now given the templatized function declaration:
template<typename T, T F>
void bar();
So bar
will be taking in a member function like so:
bar<decltype(&foo::func), &foo::func>()
In the body of bar
I want to recover the type foo
from T
. Can I do that? I want to be able to do something like this:
get_obj<T> myfoo;
(myfoo.*F)();
I know that get_obj
isn't a thing, but would there be a way to write it?
c++ templates methods member-function-pointers metatype
Given a object:
struct foo
void func();
;
Now given the templatized function declaration:
template<typename T, T F>
void bar();
So bar
will be taking in a member function like so:
bar<decltype(&foo::func), &foo::func>()
In the body of bar
I want to recover the type foo
from T
. Can I do that? I want to be able to do something like this:
get_obj<T> myfoo;
(myfoo.*F)();
I know that get_obj
isn't a thing, but would there be a way to write it?
c++ templates methods member-function-pointers metatype
c++ templates methods member-function-pointers metatype
edited 4 hours ago
asked 4 hours ago
Jonathan Mee
20.3k860151
20.3k860151
I figured I should mention that I do know that I can simplifybar
totemplate<auto F> void bar()
This just seemed simpler to write it this way.
â Jonathan Mee
4 hours ago
"something like this" do you mean to domyfoo.*F
instead offoo.*F
? And it appears you want to find the object type that a given member function is for, not the actual object?
â Yakk - Adam Nevraumont
4 hours ago
@Yakk-AdamNevraumont Yes you're right. I'm failing at freehanding code today :(
â Jonathan Mee
4 hours ago
add a comment |Â
I figured I should mention that I do know that I can simplifybar
totemplate<auto F> void bar()
This just seemed simpler to write it this way.
â Jonathan Mee
4 hours ago
"something like this" do you mean to domyfoo.*F
instead offoo.*F
? And it appears you want to find the object type that a given member function is for, not the actual object?
â Yakk - Adam Nevraumont
4 hours ago
@Yakk-AdamNevraumont Yes you're right. I'm failing at freehanding code today :(
â Jonathan Mee
4 hours ago
I figured I should mention that I do know that I can simplify
bar
to template<auto F> void bar()
This just seemed simpler to write it this way.â Jonathan Mee
4 hours ago
I figured I should mention that I do know that I can simplify
bar
to template<auto F> void bar()
This just seemed simpler to write it this way.â Jonathan Mee
4 hours ago
"something like this" do you mean to do
myfoo.*F
instead of foo.*F
? And it appears you want to find the object type that a given member function is for, not the actual object?â Yakk - Adam Nevraumont
4 hours ago
"something like this" do you mean to do
myfoo.*F
instead of foo.*F
? And it appears you want to find the object type that a given member function is for, not the actual object?â Yakk - Adam Nevraumont
4 hours ago
@Yakk-AdamNevraumont Yes you're right. I'm failing at freehanding code today :(
â Jonathan Mee
4 hours ago
@Yakk-AdamNevraumont Yes you're right. I'm failing at freehanding code today :(
â Jonathan Mee
4 hours ago
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
7
down vote
template<class T>
struct get_memfun_class;
template<class R, class T, class...Args>
struct get_memfun_class<R(T::*)(Args...)>
using type=T;
;
template<class T>
using get_memfun_class_t=typename get_memfun_class<T>::type;
template<auto M>
using class_of_memfun = get_memfun_class_t< decltype(M) >;
class_of_memfun<F>
is then the class of the memberfunction F
.
To handle const/volatile/etc you end up having to do a bunch of versions. This is annoying. Here is an example of it:
template<class T>
struct get_memfun_class;
#define GET_MEMFUN_CLASS(...)
template<class R, class T, class...Args>
struct get_memfun_class<R(T::*)(Args...) __VA_ARGS__>
using type=T;
GET_MEMFUN_CLASS();
GET_MEMFUN_CLASS(const);
GET_MEMFUN_CLASS(volatile);
GET_MEMFUN_CLASS(const volatile);
GET_MEMFUN_CLASS(&);
GET_MEMFUN_CLASS(const&);
GET_MEMFUN_CLASS(volatile&);
GET_MEMFUN_CLASS(const volatile&);
GET_MEMFUN_CLASS(&&);
GET_MEMFUN_CLASS(const&&);
GET_MEMFUN_CLASS(volatile&&);
GET_MEMFUN_CLASS(const volatile&&);
GET_MEMFUN_CLASS(noexcept);
GET_MEMFUN_CLASS(const noexcept);
GET_MEMFUN_CLASS(volatile noexcept);
GET_MEMFUN_CLASS(const volatile noexcept);
GET_MEMFUN_CLASS(& noexcept);
GET_MEMFUN_CLASS(const& noexcept);
GET_MEMFUN_CLASS(volatile& noexcept);
GET_MEMFUN_CLASS(const volatile& noexcept);
GET_MEMFUN_CLASS(&& noexcept);
GET_MEMFUN_CLASS(const&& noexcept);
GET_MEMFUN_CLASS(volatile&& noexcept);
GET_MEMFUN_CLASS(const volatile&& noexcept);
#undef GET_MEMFUN_CLASS
template<class T>
using get_memfun_class_t=typename get_memfun_class<T>::type;
I am unaware of a way to avoid doing all 24 of these specializations for full coverage.
If you are doing something like this for more than one trait, you can write the "strip lvalue, rvalue, noexcept and cv qualifiers" off part at one spot and pass them down in pieces.
Live example.
Ah, even the*_t
nice touch. So in my example I could call this like:get_memfun_class_t<T> myfoo
â Jonathan Mee
3 hours ago
OK just for my own understanding, I believe the secondget_memfun_class
is a specialization, right? Yet it takes more template arguments? I was trying to figure out how to do this by defaulting, but it looks like we can specify a different number of template arguments for a specialization?
â Jonathan Mee
3 hours ago
1
@JonathanMee as I understood, the crucial point isget_memfun_class<R(T::*)(Args...)>
on the specialization, so it actually still takes one parameter
â user463035818
3 hours ago
But thetemplate<class R, class T, class... Args>
aren't those 3 arguments? I mean I guess they can't be because objects must be fully specified on declaration, and either way this only takes one argument. But if not arguments what areR
,T
, andArgs
? Maybe this should be made into a second question...
â Jonathan Mee
3 hours ago
1
ah finally someone upvoted this but not mine. didnt feel right before
â user463035818
3 hours ago
 |Â
show 7 more comments
up vote
6
down vote
If you restrict to void(T::mem_fun)()
:
#include <iostream>
struct foo
void func() std::cout << "foo";
;
template <typename T> struct get_type;
template <typename T> struct get_type<void(T::*)()>
using type = T;
;
template <typename T> using get_type_t = typename get_type<T>::type;
template<typename T, T F> void bar()
get_type_t<T> myfoo;
(myfoo.*F)();
int main ()
bar<decltype(&foo::func), &foo::func>();
Can we extend this with something liketemplate<typename T, typename R, typename Ts...> struct get_type<R(T::*)(Ts...)> using type = T; ;
â Jonathan Mee
4 hours ago
@JonathanMee I took the(myfoo.*F)();
as given. With arbitrary return and params i guess it is possible just a bit more complicated ;)
â user463035818
4 hours ago
1
Beware that this fails forconst
,volatile
orstatic
member functions.
â François Andrieux
2 hours ago
@FrançoisAndrieuxstatic
is kinda ovious, the other cases arent that clear to me, will have to do some research. Thanks for the comment
â user463035818
2 hours ago
@user463035818 You can fix the cv problem by adding specializations liketemplate <typename T> struct get_type<void(T::*)() const>
, etc. There may be a clever solution with astd::remove_cv_t
but I don't see it.
â François Andrieux
2 hours ago
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
7
down vote
template<class T>
struct get_memfun_class;
template<class R, class T, class...Args>
struct get_memfun_class<R(T::*)(Args...)>
using type=T;
;
template<class T>
using get_memfun_class_t=typename get_memfun_class<T>::type;
template<auto M>
using class_of_memfun = get_memfun_class_t< decltype(M) >;
class_of_memfun<F>
is then the class of the memberfunction F
.
To handle const/volatile/etc you end up having to do a bunch of versions. This is annoying. Here is an example of it:
template<class T>
struct get_memfun_class;
#define GET_MEMFUN_CLASS(...)
template<class R, class T, class...Args>
struct get_memfun_class<R(T::*)(Args...) __VA_ARGS__>
using type=T;
GET_MEMFUN_CLASS();
GET_MEMFUN_CLASS(const);
GET_MEMFUN_CLASS(volatile);
GET_MEMFUN_CLASS(const volatile);
GET_MEMFUN_CLASS(&);
GET_MEMFUN_CLASS(const&);
GET_MEMFUN_CLASS(volatile&);
GET_MEMFUN_CLASS(const volatile&);
GET_MEMFUN_CLASS(&&);
GET_MEMFUN_CLASS(const&&);
GET_MEMFUN_CLASS(volatile&&);
GET_MEMFUN_CLASS(const volatile&&);
GET_MEMFUN_CLASS(noexcept);
GET_MEMFUN_CLASS(const noexcept);
GET_MEMFUN_CLASS(volatile noexcept);
GET_MEMFUN_CLASS(const volatile noexcept);
GET_MEMFUN_CLASS(& noexcept);
GET_MEMFUN_CLASS(const& noexcept);
GET_MEMFUN_CLASS(volatile& noexcept);
GET_MEMFUN_CLASS(const volatile& noexcept);
GET_MEMFUN_CLASS(&& noexcept);
GET_MEMFUN_CLASS(const&& noexcept);
GET_MEMFUN_CLASS(volatile&& noexcept);
GET_MEMFUN_CLASS(const volatile&& noexcept);
#undef GET_MEMFUN_CLASS
template<class T>
using get_memfun_class_t=typename get_memfun_class<T>::type;
I am unaware of a way to avoid doing all 24 of these specializations for full coverage.
If you are doing something like this for more than one trait, you can write the "strip lvalue, rvalue, noexcept and cv qualifiers" off part at one spot and pass them down in pieces.
Live example.
Ah, even the*_t
nice touch. So in my example I could call this like:get_memfun_class_t<T> myfoo
â Jonathan Mee
3 hours ago
OK just for my own understanding, I believe the secondget_memfun_class
is a specialization, right? Yet it takes more template arguments? I was trying to figure out how to do this by defaulting, but it looks like we can specify a different number of template arguments for a specialization?
â Jonathan Mee
3 hours ago
1
@JonathanMee as I understood, the crucial point isget_memfun_class<R(T::*)(Args...)>
on the specialization, so it actually still takes one parameter
â user463035818
3 hours ago
But thetemplate<class R, class T, class... Args>
aren't those 3 arguments? I mean I guess they can't be because objects must be fully specified on declaration, and either way this only takes one argument. But if not arguments what areR
,T
, andArgs
? Maybe this should be made into a second question...
â Jonathan Mee
3 hours ago
1
ah finally someone upvoted this but not mine. didnt feel right before
â user463035818
3 hours ago
 |Â
show 7 more comments
up vote
7
down vote
template<class T>
struct get_memfun_class;
template<class R, class T, class...Args>
struct get_memfun_class<R(T::*)(Args...)>
using type=T;
;
template<class T>
using get_memfun_class_t=typename get_memfun_class<T>::type;
template<auto M>
using class_of_memfun = get_memfun_class_t< decltype(M) >;
class_of_memfun<F>
is then the class of the memberfunction F
.
To handle const/volatile/etc you end up having to do a bunch of versions. This is annoying. Here is an example of it:
template<class T>
struct get_memfun_class;
#define GET_MEMFUN_CLASS(...)
template<class R, class T, class...Args>
struct get_memfun_class<R(T::*)(Args...) __VA_ARGS__>
using type=T;
GET_MEMFUN_CLASS();
GET_MEMFUN_CLASS(const);
GET_MEMFUN_CLASS(volatile);
GET_MEMFUN_CLASS(const volatile);
GET_MEMFUN_CLASS(&);
GET_MEMFUN_CLASS(const&);
GET_MEMFUN_CLASS(volatile&);
GET_MEMFUN_CLASS(const volatile&);
GET_MEMFUN_CLASS(&&);
GET_MEMFUN_CLASS(const&&);
GET_MEMFUN_CLASS(volatile&&);
GET_MEMFUN_CLASS(const volatile&&);
GET_MEMFUN_CLASS(noexcept);
GET_MEMFUN_CLASS(const noexcept);
GET_MEMFUN_CLASS(volatile noexcept);
GET_MEMFUN_CLASS(const volatile noexcept);
GET_MEMFUN_CLASS(& noexcept);
GET_MEMFUN_CLASS(const& noexcept);
GET_MEMFUN_CLASS(volatile& noexcept);
GET_MEMFUN_CLASS(const volatile& noexcept);
GET_MEMFUN_CLASS(&& noexcept);
GET_MEMFUN_CLASS(const&& noexcept);
GET_MEMFUN_CLASS(volatile&& noexcept);
GET_MEMFUN_CLASS(const volatile&& noexcept);
#undef GET_MEMFUN_CLASS
template<class T>
using get_memfun_class_t=typename get_memfun_class<T>::type;
I am unaware of a way to avoid doing all 24 of these specializations for full coverage.
If you are doing something like this for more than one trait, you can write the "strip lvalue, rvalue, noexcept and cv qualifiers" off part at one spot and pass them down in pieces.
Live example.
Ah, even the*_t
nice touch. So in my example I could call this like:get_memfun_class_t<T> myfoo
â Jonathan Mee
3 hours ago
OK just for my own understanding, I believe the secondget_memfun_class
is a specialization, right? Yet it takes more template arguments? I was trying to figure out how to do this by defaulting, but it looks like we can specify a different number of template arguments for a specialization?
â Jonathan Mee
3 hours ago
1
@JonathanMee as I understood, the crucial point isget_memfun_class<R(T::*)(Args...)>
on the specialization, so it actually still takes one parameter
â user463035818
3 hours ago
But thetemplate<class R, class T, class... Args>
aren't those 3 arguments? I mean I guess they can't be because objects must be fully specified on declaration, and either way this only takes one argument. But if not arguments what areR
,T
, andArgs
? Maybe this should be made into a second question...
â Jonathan Mee
3 hours ago
1
ah finally someone upvoted this but not mine. didnt feel right before
â user463035818
3 hours ago
 |Â
show 7 more comments
up vote
7
down vote
up vote
7
down vote
template<class T>
struct get_memfun_class;
template<class R, class T, class...Args>
struct get_memfun_class<R(T::*)(Args...)>
using type=T;
;
template<class T>
using get_memfun_class_t=typename get_memfun_class<T>::type;
template<auto M>
using class_of_memfun = get_memfun_class_t< decltype(M) >;
class_of_memfun<F>
is then the class of the memberfunction F
.
To handle const/volatile/etc you end up having to do a bunch of versions. This is annoying. Here is an example of it:
template<class T>
struct get_memfun_class;
#define GET_MEMFUN_CLASS(...)
template<class R, class T, class...Args>
struct get_memfun_class<R(T::*)(Args...) __VA_ARGS__>
using type=T;
GET_MEMFUN_CLASS();
GET_MEMFUN_CLASS(const);
GET_MEMFUN_CLASS(volatile);
GET_MEMFUN_CLASS(const volatile);
GET_MEMFUN_CLASS(&);
GET_MEMFUN_CLASS(const&);
GET_MEMFUN_CLASS(volatile&);
GET_MEMFUN_CLASS(const volatile&);
GET_MEMFUN_CLASS(&&);
GET_MEMFUN_CLASS(const&&);
GET_MEMFUN_CLASS(volatile&&);
GET_MEMFUN_CLASS(const volatile&&);
GET_MEMFUN_CLASS(noexcept);
GET_MEMFUN_CLASS(const noexcept);
GET_MEMFUN_CLASS(volatile noexcept);
GET_MEMFUN_CLASS(const volatile noexcept);
GET_MEMFUN_CLASS(& noexcept);
GET_MEMFUN_CLASS(const& noexcept);
GET_MEMFUN_CLASS(volatile& noexcept);
GET_MEMFUN_CLASS(const volatile& noexcept);
GET_MEMFUN_CLASS(&& noexcept);
GET_MEMFUN_CLASS(const&& noexcept);
GET_MEMFUN_CLASS(volatile&& noexcept);
GET_MEMFUN_CLASS(const volatile&& noexcept);
#undef GET_MEMFUN_CLASS
template<class T>
using get_memfun_class_t=typename get_memfun_class<T>::type;
I am unaware of a way to avoid doing all 24 of these specializations for full coverage.
If you are doing something like this for more than one trait, you can write the "strip lvalue, rvalue, noexcept and cv qualifiers" off part at one spot and pass them down in pieces.
Live example.
template<class T>
struct get_memfun_class;
template<class R, class T, class...Args>
struct get_memfun_class<R(T::*)(Args...)>
using type=T;
;
template<class T>
using get_memfun_class_t=typename get_memfun_class<T>::type;
template<auto M>
using class_of_memfun = get_memfun_class_t< decltype(M) >;
class_of_memfun<F>
is then the class of the memberfunction F
.
To handle const/volatile/etc you end up having to do a bunch of versions. This is annoying. Here is an example of it:
template<class T>
struct get_memfun_class;
#define GET_MEMFUN_CLASS(...)
template<class R, class T, class...Args>
struct get_memfun_class<R(T::*)(Args...) __VA_ARGS__>
using type=T;
GET_MEMFUN_CLASS();
GET_MEMFUN_CLASS(const);
GET_MEMFUN_CLASS(volatile);
GET_MEMFUN_CLASS(const volatile);
GET_MEMFUN_CLASS(&);
GET_MEMFUN_CLASS(const&);
GET_MEMFUN_CLASS(volatile&);
GET_MEMFUN_CLASS(const volatile&);
GET_MEMFUN_CLASS(&&);
GET_MEMFUN_CLASS(const&&);
GET_MEMFUN_CLASS(volatile&&);
GET_MEMFUN_CLASS(const volatile&&);
GET_MEMFUN_CLASS(noexcept);
GET_MEMFUN_CLASS(const noexcept);
GET_MEMFUN_CLASS(volatile noexcept);
GET_MEMFUN_CLASS(const volatile noexcept);
GET_MEMFUN_CLASS(& noexcept);
GET_MEMFUN_CLASS(const& noexcept);
GET_MEMFUN_CLASS(volatile& noexcept);
GET_MEMFUN_CLASS(const volatile& noexcept);
GET_MEMFUN_CLASS(&& noexcept);
GET_MEMFUN_CLASS(const&& noexcept);
GET_MEMFUN_CLASS(volatile&& noexcept);
GET_MEMFUN_CLASS(const volatile&& noexcept);
#undef GET_MEMFUN_CLASS
template<class T>
using get_memfun_class_t=typename get_memfun_class<T>::type;
I am unaware of a way to avoid doing all 24 of these specializations for full coverage.
If you are doing something like this for more than one trait, you can write the "strip lvalue, rvalue, noexcept and cv qualifiers" off part at one spot and pass them down in pieces.
Live example.
edited 2 hours ago
answered 3 hours ago
Yakk - Adam Nevraumont
170k18173349
170k18173349
Ah, even the*_t
nice touch. So in my example I could call this like:get_memfun_class_t<T> myfoo
â Jonathan Mee
3 hours ago
OK just for my own understanding, I believe the secondget_memfun_class
is a specialization, right? Yet it takes more template arguments? I was trying to figure out how to do this by defaulting, but it looks like we can specify a different number of template arguments for a specialization?
â Jonathan Mee
3 hours ago
1
@JonathanMee as I understood, the crucial point isget_memfun_class<R(T::*)(Args...)>
on the specialization, so it actually still takes one parameter
â user463035818
3 hours ago
But thetemplate<class R, class T, class... Args>
aren't those 3 arguments? I mean I guess they can't be because objects must be fully specified on declaration, and either way this only takes one argument. But if not arguments what areR
,T
, andArgs
? Maybe this should be made into a second question...
â Jonathan Mee
3 hours ago
1
ah finally someone upvoted this but not mine. didnt feel right before
â user463035818
3 hours ago
 |Â
show 7 more comments
Ah, even the*_t
nice touch. So in my example I could call this like:get_memfun_class_t<T> myfoo
â Jonathan Mee
3 hours ago
OK just for my own understanding, I believe the secondget_memfun_class
is a specialization, right? Yet it takes more template arguments? I was trying to figure out how to do this by defaulting, but it looks like we can specify a different number of template arguments for a specialization?
â Jonathan Mee
3 hours ago
1
@JonathanMee as I understood, the crucial point isget_memfun_class<R(T::*)(Args...)>
on the specialization, so it actually still takes one parameter
â user463035818
3 hours ago
But thetemplate<class R, class T, class... Args>
aren't those 3 arguments? I mean I guess they can't be because objects must be fully specified on declaration, and either way this only takes one argument. But if not arguments what areR
,T
, andArgs
? Maybe this should be made into a second question...
â Jonathan Mee
3 hours ago
1
ah finally someone upvoted this but not mine. didnt feel right before
â user463035818
3 hours ago
Ah, even the
*_t
nice touch. So in my example I could call this like: get_memfun_class_t<T> myfoo
â Jonathan Mee
3 hours ago
Ah, even the
*_t
nice touch. So in my example I could call this like: get_memfun_class_t<T> myfoo
â Jonathan Mee
3 hours ago
OK just for my own understanding, I believe the second
get_memfun_class
is a specialization, right? Yet it takes more template arguments? I was trying to figure out how to do this by defaulting, but it looks like we can specify a different number of template arguments for a specialization?â Jonathan Mee
3 hours ago
OK just for my own understanding, I believe the second
get_memfun_class
is a specialization, right? Yet it takes more template arguments? I was trying to figure out how to do this by defaulting, but it looks like we can specify a different number of template arguments for a specialization?â Jonathan Mee
3 hours ago
1
1
@JonathanMee as I understood, the crucial point is
get_memfun_class<R(T::*)(Args...)>
on the specialization, so it actually still takes one parameterâ user463035818
3 hours ago
@JonathanMee as I understood, the crucial point is
get_memfun_class<R(T::*)(Args...)>
on the specialization, so it actually still takes one parameterâ user463035818
3 hours ago
But the
template<class R, class T, class... Args>
aren't those 3 arguments? I mean I guess they can't be because objects must be fully specified on declaration, and either way this only takes one argument. But if not arguments what are R
, T
, and Args
? Maybe this should be made into a second question...â Jonathan Mee
3 hours ago
But the
template<class R, class T, class... Args>
aren't those 3 arguments? I mean I guess they can't be because objects must be fully specified on declaration, and either way this only takes one argument. But if not arguments what are R
, T
, and Args
? Maybe this should be made into a second question...â Jonathan Mee
3 hours ago
1
1
ah finally someone upvoted this but not mine. didnt feel right before
â user463035818
3 hours ago
ah finally someone upvoted this but not mine. didnt feel right before
â user463035818
3 hours ago
 |Â
show 7 more comments
up vote
6
down vote
If you restrict to void(T::mem_fun)()
:
#include <iostream>
struct foo
void func() std::cout << "foo";
;
template <typename T> struct get_type;
template <typename T> struct get_type<void(T::*)()>
using type = T;
;
template <typename T> using get_type_t = typename get_type<T>::type;
template<typename T, T F> void bar()
get_type_t<T> myfoo;
(myfoo.*F)();
int main ()
bar<decltype(&foo::func), &foo::func>();
Can we extend this with something liketemplate<typename T, typename R, typename Ts...> struct get_type<R(T::*)(Ts...)> using type = T; ;
â Jonathan Mee
4 hours ago
@JonathanMee I took the(myfoo.*F)();
as given. With arbitrary return and params i guess it is possible just a bit more complicated ;)
â user463035818
4 hours ago
1
Beware that this fails forconst
,volatile
orstatic
member functions.
â François Andrieux
2 hours ago
@FrançoisAndrieuxstatic
is kinda ovious, the other cases arent that clear to me, will have to do some research. Thanks for the comment
â user463035818
2 hours ago
@user463035818 You can fix the cv problem by adding specializations liketemplate <typename T> struct get_type<void(T::*)() const>
, etc. There may be a clever solution with astd::remove_cv_t
but I don't see it.
â François Andrieux
2 hours ago
add a comment |Â
up vote
6
down vote
If you restrict to void(T::mem_fun)()
:
#include <iostream>
struct foo
void func() std::cout << "foo";
;
template <typename T> struct get_type;
template <typename T> struct get_type<void(T::*)()>
using type = T;
;
template <typename T> using get_type_t = typename get_type<T>::type;
template<typename T, T F> void bar()
get_type_t<T> myfoo;
(myfoo.*F)();
int main ()
bar<decltype(&foo::func), &foo::func>();
Can we extend this with something liketemplate<typename T, typename R, typename Ts...> struct get_type<R(T::*)(Ts...)> using type = T; ;
â Jonathan Mee
4 hours ago
@JonathanMee I took the(myfoo.*F)();
as given. With arbitrary return and params i guess it is possible just a bit more complicated ;)
â user463035818
4 hours ago
1
Beware that this fails forconst
,volatile
orstatic
member functions.
â François Andrieux
2 hours ago
@FrançoisAndrieuxstatic
is kinda ovious, the other cases arent that clear to me, will have to do some research. Thanks for the comment
â user463035818
2 hours ago
@user463035818 You can fix the cv problem by adding specializations liketemplate <typename T> struct get_type<void(T::*)() const>
, etc. There may be a clever solution with astd::remove_cv_t
but I don't see it.
â François Andrieux
2 hours ago
add a comment |Â
up vote
6
down vote
up vote
6
down vote
If you restrict to void(T::mem_fun)()
:
#include <iostream>
struct foo
void func() std::cout << "foo";
;
template <typename T> struct get_type;
template <typename T> struct get_type<void(T::*)()>
using type = T;
;
template <typename T> using get_type_t = typename get_type<T>::type;
template<typename T, T F> void bar()
get_type_t<T> myfoo;
(myfoo.*F)();
int main ()
bar<decltype(&foo::func), &foo::func>();
If you restrict to void(T::mem_fun)()
:
#include <iostream>
struct foo
void func() std::cout << "foo";
;
template <typename T> struct get_type;
template <typename T> struct get_type<void(T::*)()>
using type = T;
;
template <typename T> using get_type_t = typename get_type<T>::type;
template<typename T, T F> void bar()
get_type_t<T> myfoo;
(myfoo.*F)();
int main ()
bar<decltype(&foo::func), &foo::func>();
edited 3 hours ago
answered 4 hours ago
user463035818
14.1k22256
14.1k22256
Can we extend this with something liketemplate<typename T, typename R, typename Ts...> struct get_type<R(T::*)(Ts...)> using type = T; ;
â Jonathan Mee
4 hours ago
@JonathanMee I took the(myfoo.*F)();
as given. With arbitrary return and params i guess it is possible just a bit more complicated ;)
â user463035818
4 hours ago
1
Beware that this fails forconst
,volatile
orstatic
member functions.
â François Andrieux
2 hours ago
@FrançoisAndrieuxstatic
is kinda ovious, the other cases arent that clear to me, will have to do some research. Thanks for the comment
â user463035818
2 hours ago
@user463035818 You can fix the cv problem by adding specializations liketemplate <typename T> struct get_type<void(T::*)() const>
, etc. There may be a clever solution with astd::remove_cv_t
but I don't see it.
â François Andrieux
2 hours ago
add a comment |Â
Can we extend this with something liketemplate<typename T, typename R, typename Ts...> struct get_type<R(T::*)(Ts...)> using type = T; ;
â Jonathan Mee
4 hours ago
@JonathanMee I took the(myfoo.*F)();
as given. With arbitrary return and params i guess it is possible just a bit more complicated ;)
â user463035818
4 hours ago
1
Beware that this fails forconst
,volatile
orstatic
member functions.
â François Andrieux
2 hours ago
@FrançoisAndrieuxstatic
is kinda ovious, the other cases arent that clear to me, will have to do some research. Thanks for the comment
â user463035818
2 hours ago
@user463035818 You can fix the cv problem by adding specializations liketemplate <typename T> struct get_type<void(T::*)() const>
, etc. There may be a clever solution with astd::remove_cv_t
but I don't see it.
â François Andrieux
2 hours ago
Can we extend this with something like
template<typename T, typename R, typename Ts...> struct get_type<R(T::*)(Ts...)> using type = T; ;
â Jonathan Mee
4 hours ago
Can we extend this with something like
template<typename T, typename R, typename Ts...> struct get_type<R(T::*)(Ts...)> using type = T; ;
â Jonathan Mee
4 hours ago
@JonathanMee I took the
(myfoo.*F)();
as given. With arbitrary return and params i guess it is possible just a bit more complicated ;)â user463035818
4 hours ago
@JonathanMee I took the
(myfoo.*F)();
as given. With arbitrary return and params i guess it is possible just a bit more complicated ;)â user463035818
4 hours ago
1
1
Beware that this fails for
const
, volatile
or static
member functions.â François Andrieux
2 hours ago
Beware that this fails for
const
, volatile
or static
member functions.â François Andrieux
2 hours ago
@FrançoisAndrieux
static
is kinda ovious, the other cases arent that clear to me, will have to do some research. Thanks for the commentâ user463035818
2 hours ago
@FrançoisAndrieux
static
is kinda ovious, the other cases arent that clear to me, will have to do some research. Thanks for the commentâ user463035818
2 hours ago
@user463035818 You can fix the cv problem by adding specializations like
template <typename T> struct get_type<void(T::*)() const>
, etc. There may be a clever solution with a std::remove_cv_t
but I don't see it.â François Andrieux
2 hours ago
@user463035818 You can fix the cv problem by adding specializations like
template <typename T> struct get_type<void(T::*)() const>
, etc. There may be a clever solution with a std::remove_cv_t
but I don't see it.â François Andrieux
2 hours ago
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52317134%2fcan-i-get-the-owning-object-of-a-member-function-template-parameter%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
I figured I should mention that I do know that I can simplify
bar
totemplate<auto F> void bar()
This just seemed simpler to write it this way.â Jonathan Mee
4 hours ago
"something like this" do you mean to do
myfoo.*F
instead offoo.*F
? And it appears you want to find the object type that a given member function is for, not the actual object?â Yakk - Adam Nevraumont
4 hours ago
@Yakk-AdamNevraumont Yes you're right. I'm failing at freehanding code today :(
â Jonathan Mee
4 hours ago