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]:
templateconstexpr T& get(tuple & t) noexcept; // and the other like overloads Requires: The type
Toccurs 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::getnot 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.