In C++11, it is easy to SFINAE on whether or not an expression is valid. As an example, imagine checking if something is streamable:
template <typename T>
auto print_if_possible(std::ostream& os, const T& x)
-> decltype(os << x, void());
print_if_possible
will only participate in overload resolution if os << x
is a well-formed expression.
live example on godbolt.org
I need to do the same in C++03, and I figured out that sizeof
could help (as I needed an unevaluated context for an expression). This is what I came up with:
template <int> struct sfinaer { };
template <typename T>
void print_if_possible(std::ostream& os, const T& x,
sfinaer<sizeof(os << x)>* = NULL);
live example on godbolt.org
It seems that both the latest versions of g++ and clang++ accept the sizeof
version with -std=c++03 -Wall -Wextra
.
Is the code guaranteed to work as intended in C++03?
Is it correct to conclude that any usage of C++11 expression SFINAE can be backported to C++03 using sfinaer
and sizeof
?
Expression SFINAE is a bit gray. C++03 basically said nothing on the subject. It neither explicitly banned it nor explicitly allowed it. Contemporary implementations did not permit such constructs because it caused substantial implementation complexity and it's unclear whether it's meant to be allowed, and CWG was at one point leaning towards banning it (see the April, 2003 note) before it eventually reversed course, partially in light of decltype
and constexpr
that were added to C++11 (see the introduction to N2634).
This also all happened well before CWG started explicitly marking the DR status of issues whose resolutions are meant to apply retroactively.
I think the best advice here is simply "ask your compiler vendor". A compiler that supports expression SFINAE in its C++11 mode is unlikely to tear out that support in C++03 mode (the vendor may treat CWG 339 as a defect report and apply it retroactively, or consider it as an extension). OTOH, a compiler that never supported C++11 is unlikely to invest the substantial costs necessary for expression SFINAE to work (indeed, it did not work in a certain major compiler cough until relatively recently). I also suspect that a place still stuck with an 15-year-old language is unlikely to use the modern toolchains necessary for such support.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With