I've been using code similar to the following in MSVC projects for the last year or so, and ran into an issue trying to use it with g++.
#include <utility>
#include <glm/glm.hpp>
namespace std {
template< std::size_t I, auto N, class T, auto Q>
constexpr auto& get(glm::vec<N, T, Q>& v) noexcept { return v[I]; }
template< std::size_t I, auto N, class T, auto Q>
constexpr const auto& get(const glm::vec<N, T, Q>& v) noexcept { return v[I]; }
template< std::size_t I, auto N, class T, auto Q>
constexpr auto&& get(glm::vec<N, T, Q>&& v) noexcept { return std::move(v[I]); }
template< std::size_t I, auto N, class T, auto Q>
constexpr const auto&& get(const glm::vec<N, T, Q>&& v) noexcept { return std::move(v[I]); }
template <auto N, class T, auto Q>
struct tuple_size<glm::vec<N, T, Q>> : std::integral_constant<std::size_t, N> { };
template <std::size_t I, auto N, class T, auto Q>
struct tuple_element<I, glm::vec<N, T, Q>> {
using type = decltype(get<I>(declval<glm::vec<N,T,Q>>()));
};
}// end std
auto f(){
auto [x,y,z] = glm::vec3(1);
return x + y + z;
}
GCC gives the error error: 'get' was not declared in this scope; did you mean 'std::get'?
Clang gives the error error: use of undeclared identifier 'get'
icc and MSVC both compile properly.
I'm wondering if this has something to do with GLM's implementation, because I've never had issues with custom structured bindings with GCC in the past.
I was wondering if anyone knows what is going on here. Are icc and MSVC behaving incorrectly by accepting the code, or are Clang and GCC behaving incorrectly by rejecting the code?
Here's an example of the four different compilers handling this on Compiler Explorer: https://godbolt.org/z/6PCWyn