https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115808
--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Without the library dependency:
struct _ignore {
template<class T> constexpr const _ignore& operator=(const T&) const { return
*this; }
};
constexpr _ignore ignore{};
namespace utempl::loopholes {
template <auto I>
struct Getter {
friend constexpr auto Magic(Getter<I>);
};
template <auto I, auto Value = 0>
struct Injector {
friend constexpr auto Magic(Getter<I>) {
return Value;
};
};
} // namespace utempl::loopholes
namespace utempl {
template <typename... Ts>
struct TypeList {};
} // namespace utempl
struct SomeStruct {
constexpr SomeStruct(auto&& arg) {
arg.Method(42);
};
};
struct Injector {
template <typename T, auto _ = utempl::loopholes::Injector<0,
utempl::TypeList<T>{}>{}>
auto Method(T&&) const -> void;
};
template <typename T, auto... Args>
inline constexpr auto Use() {
ignore = T{Args...};
};
template <typename...>
consteval auto Ignore() {};
template<class, class> constexpr bool is_same_v = false;
template<class T> constexpr bool is_same_v<T,T> = true;
auto main() -> int {
Ignore<decltype(Use<SomeStruct, Injector{}>())>();
static_assert(is_same_v<decltype(Magic(utempl::loopholes::Getter<0>{})),
utempl::TypeList<int>>); // Passes with optimizations. Not passes without
};