SFINAE

Hi guys,

I am following along with this tutorial from a blog post

https://jguegant.github.io/blogs/tech/sfinae-introduction.html

// reallyHas<std::string (C::*)(), &C::serialize> should be substituted by
// reallyHas<std::string (C::*)(), std::string (C::*)() &C::serialize> and work!

the above lines really get me,ok so we are calling reallyHas with the template arguments<std::string (C::*)(), &C::serialize>,I understand where he gets string from but what is (C::*)(),it looks like a function pointer but I don't think it is,

could someone help explain what is going on

thanks :)
std::string (C::*) is a pointer to a non-static member function of class C that accepts no parameters and returns an std::string.
std::string (C::*)() is a function (or callable. I'm unsure) that returns a pointer of the aforementioned type.

It looks pretty awful. It could use a typedef.
1
2
3
typedef std::string (C::*fp);

reallyHas<fp(), fp() &C::serialize>
Last edited on
std::string (C::*)() is the type of a pointer-to-member-function of class C returning std::string and accepting no arguments. std::string (C::*) is just nonsense the type of a std::string data member of class C, with extraneous parentheses.

To define a function named f accepting int and returning a pointer-to-member function of class C returning std::string and accepting no arguments, you'd write std::string (C::*f(int))() { return &C::member; }, to be used like (c.*f(42))();

Use a typedef, please.
Last edited on
helios wrote:
std::string (C::*) is a pointer to a non-static member function of class C that accepts no parameters and returns an std::string.
mbozzi wrote:
std::string (C::*) is just nonsense.

std::string (C::*) is a pointer to a std::string member of class C.

http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_data_members
Hm... So, without a typedef, what would be a function returning an std::string member of C?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>

struct C
{
	std::string str;
};

std::string (C::*f())
{
	return &C::str;
}

int main()
{
	C x{"xyz"};
	std::string (C::*y) = f();
	std::cout << x.*y; // prints xyz 
}


Note that the parentheses are not strictly necessary here, so

std::string (C::*f()) could be written as std::string C::* f(), and

std::string (C::*y) = f(); could be written as std::string C::* y = f();.
ahh that would make a bit more sense Peter vv

std::string (C::*) is a pointer to a std::string member of class C.


putting the pointer in parenthesis kind of confused me,is there a reason why he did this?

also what are the next set of empty parenthesis for?

when passing it as a template argument, reallyHas<std::string (C::*)(), &C::serialize>

is the type an std::string or what is it?



thanks
Last edited on
My previous post was mainly in response to what helios said.

When it comes to pointers to member functions the first set of parentheses are necessary for it to parse correctly. The second pair of parentheses contains the list of parameter types.

std::string (C::*)() is a pointer to a member function of class C that takes no arguments and returns a std::string.

std::string (C::*)(int) is a pointer to a member function of class C that takes one argument of type int and returns a std::string.
Last edited on
std::string (C::*)() is a pointer to a member function of class C that takes no arguments and returns a std::string.


oh ok,but how can we dereference/use that pointer because it has no name?


thanks
It's a type.
not really following you Peter,

int (*p)(void*,void*) would be a function pointer to a function that returns an int and accepts two void pointers as arguments

std::string (C::*)() as you mentioned is pretty much a function pointer to a member function of class C that takes no arguments and returns a std::string

we can assign p the first function pointer to a function with p = &function
but how can we use the second one when it doesn't even have a name

and how is it a type?

thanks

int (*p)(void*,void*);, so p is a pointer.
int *q;, so q is a pointer.

int (*)(void*,void*) is a type.
int * is a type.
Last edited on
Topic archived. No new replies allowed.