I'm not a language lawyer, so I'm going to be answering this question as directly as possible.
ignore
is found in the synopsis of tuple
in tuple.general
as such:
// [tuple.creation], tuple creation functions:
const unspecified ignore;
As you noticed, the libstdc++ implementation defines ignore
like this:
// A class (and instance) which can be used in 'tie' when an element
// of a tuple is not required
struct _Swallow_assign
{
template<class _Tp>
const _Swallow_assign&
operator=(const _Tp&) const
{ return *this; }
};
Whereas the libc++ version defines it like this:
template <class _Up>
struct __ignore_t
{
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY
const __ignore_t& operator=(_Tp&&) const {return *this;}
};
As such, it compiles in libc++. Now the definition of std::tie
can be found in [tuple.creation] which says:
Returns: tuple<Types&...>(t...)
. When an argument in t
is
ignore
, assigning any value to the corresponding tuple element has
no effect.
This doesn't say anything about ignore
itself, so I'm going to chalk this up to unspecified behavior. You can argue it's undefined behavior by omission, but that might be stretching it.