Uwaga! Troll post (namówili mnie).
Istnieje wiele możliwych sposobów żeby dokonać tej prostej akcji, więc podsyłam jeden z nich (kod pisany na szybko). Na pierwszy rzut oka wygląda strasznie, ale potem jest tylko gorzej.
struct {
template <typename T, auto... Is>
auto operator () (T* Ptr1, T* Ptr2, T* Buffer, std::index_sequence<Is...>) const noexcept
{
((Buffer[Is] = Ptr1[Is]), ...);
((Ptr1[Is] = Ptr2[Is]), ...);
((Ptr2[Is] = Buffer[Is]), ...);
}
} inline constexpr Variadic;
inline constexpr auto swap = [](auto& First, auto& Second)
{
static_assert(std::is_same_v<decltype(First), decltype(Second)>);
constexpr auto TypeSize = sizeof(std::common_type_t<decltype(First), decltype(Second)>);
auto FirstPtr = reinterpret_cast<char*>(std::addressof(First));
auto SecondPtr = reinterpret_cast<char*>(std::addressof(Second));
struct { char m_Buffer[TypeSize]; } Buffer;
Variadic(FirstPtr, SecondPtr, reinterpret_cast<char*>(std::addressof(Buffer)), std::make_index_sequence<TypeSize>{});
};
int main()
{
int x = 10;
int y = 15;
std::cout << x << ' ' << y << '\n'; // 10 15
swap(x, y);
std::cout << x << ' ' << y << '\n'; // 15 10
}