Can I get the Owning Object of a Member Function Template Parameter?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
7
down vote

favorite
1












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?










share|improve this question























  • 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










  • @Yakk-AdamNevraumont Yes you're right. I'm failing at freehanding code today :(
    – Jonathan Mee
    4 hours ago














up vote
7
down vote

favorite
1












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?










share|improve this question























  • 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










  • @Yakk-AdamNevraumont Yes you're right. I'm failing at freehanding code today :(
    – Jonathan Mee
    4 hours ago












up vote
7
down vote

favorite
1









up vote
7
down vote

favorite
1






1





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?










share|improve this question















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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










  • @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










  • "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















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












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.






share|improve this answer






















  • 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






  • 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










  • 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




    ah finally someone upvoted this but not mine. didnt feel right before
    – user463035818
    3 hours ago

















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>();






share|improve this answer






















  • 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






  • 1




    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










  • @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










Your Answer





StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















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






























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.






share|improve this answer






















  • 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






  • 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










  • 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




    ah finally someone upvoted this but not mine. didnt feel right before
    – user463035818
    3 hours ago














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.






share|improve this answer






















  • 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






  • 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










  • 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




    ah finally someone upvoted this but not mine. didnt feel right before
    – user463035818
    3 hours ago












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.






share|improve this answer














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.







share|improve this answer














share|improve this answer



share|improve this answer








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 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




    @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






  • 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











  • 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




    @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






  • 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












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>();






share|improve this answer






















  • 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






  • 1




    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










  • @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














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>();






share|improve this answer






















  • 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






  • 1




    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










  • @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












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>();






share|improve this answer














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>();







share|improve this answer














share|improve this answer



share|improve this answer








edited 3 hours ago

























answered 4 hours ago









user463035818

14.1k22256




14.1k22256











  • 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






  • 1




    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










  • @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
















  • 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






  • 1




    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










  • @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















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

















 

draft saved


draft discarded















































 


draft saved


draft discarded














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













































































Comments

Popular posts from this blog

What does second last employer means? [closed]

Installing NextGIS Connect into QGIS 3?

One-line joke