std::get
does not seem to be SFINAE-friendly, as shown by the following test case:
template
auto foo(C &c) -> declty
std::get
is explicitly not SFINAE-friendly, as per [tuple.elem]:
template
constexpr T& get(tuple & t) noexcept; // and the other like overloads Requires: The type
T
occurs exactly once inTypes...
. Otherwise, the program is ill-formed.
std::get
is also explicitly not SFINAE-friendly.
As far as the other questions:
Is there a reason for
std::get
not to be SFINAE-friendly?
Don't know. Typically, this isn't a point that needs to be SFINAE-ed on. So I guess it wasn't considered something that needed to be done. Hard errors are a lot easier to understand than scrolling through a bunch of non-viable candidate options. If you believe there to be compelling reason for std::get
to be SFINAE-friendly, you could submit an LWG issue about it.
Is there a better workaround than what is outlined above?
Sure. You could write your own SFINAE-friendly verison of get
(please note, it uses C++17 fold expression):
template ::value + ...) == 1, int> = 0>
constexpr T& my_get(tuple& t) noexcept {
return std::get(t);
}
And then do with that as you wish.