
C++'s SFINAE concept: compile-time introspection of a class - jguegant
http://jguegant.github.io/blogs/tech/sfinae-introduction.html
======
weland
I'm a little... confused is maybe too strong a word for this, I just don't
really grok this:

> As you can see, during serialization, it comes pretty handy to be able to
> check if an object has an attribute and to query the type of this attribute.
> In our case, it permits us to use the serialize method if available and fall
> back to the more generic method str otherwise.

I would actually prefer if, during serialization, the compiler would yell at
me that object C doesn't have a serialize method. For one thing, it's very
likely that, while it does have a toString() method, it doesn't have the
corresponding fromString() method, making the serialized output useless. For
the other, in a sane architecture, if an object does not have a serialize()
method, then it's either: a) because it shouldn't be serialized in the first
place, whatever the reason, or b) because _it should_ have a serialize()
method, but it has not yet been implemented (and it should!)

I understand that this is "didactic" example. Does anyone know of a more real-
life/relevant example where this can be used? SFINAE (Substitution Failure Is
Not An Error) looks neat as a language feature but I don't really see where
it's useful (in fact, it looks like a bug that was repurposed as a feature).

~~~
zeroonetwothree
The original purpose of SFINAE is to solve a critical problem--if you have
multiple template versions of a function available, they don't all have to be
valid for a given call. For example say you want to have a "first" operator
that takes the first item of a container, but also works on individual values
if they aren't containers:

template<class Container> Container::value_type first(Container&& c) { return
*c.begin(); }

template<class ValueType> ValueType first(ValueType&& vt) { return vt; }

// Usage: first<int>(1); // 1

This call doesn't cause a compile error even though int::value_type does not
exist--this is SFINAE. To make this work properly you'd also need to use
compile-time introspection to disable the second function for types that have
value_type, otherwise it's ambiguous.

~~~
weland
> For example say you want to have a "first" operator that takes the first
> item of a container, but also works on individual values if they aren't
> containers:

But why would I want to do such a thing? Not only does first() not make sense
for non-container objects -- but calling x.first() when x is a non-container
object is a bug 9 times out of 10 (i.e. something got unpacked when it
shouldn't have, an [x] (a single-object vector) ended up x (i.e. the first and
only value of that vector).

~~~
MichaelGG
SFINAE looks like a cheap way to sort of hack around lack of static duck
typing. Otherwise these examples could be written in a positive way by saying
a certain function only applies to a type containing certain members or
constraints.

------
oldmanjay
It's clever. I admire and fear cleverness.

~~~
kabdib
... and I never use clever in production. :-)

