OK, thanks. So I guess the eagerness of the template machinery is not something you can work around. Perhaps the only way around this is to avoid std::conjunction and explicitly encode a staged evaluation, for instance: template <typename T> constexpr bool is_barable_v = std::decay_t<T>::barable::value; template <typename T, typename = void> struct is_fooable : std::false_type {}; template <typename T> struct is_fooable<T, std::void_t<typename std::decay_t<T>::baz>> : std::bool_constant<!is_barable_v<T>> {}; struct Foo { using barable = std::false_type; using baz = bool; }; Best regards, /Johan On Wed, May 29, 2019 at 12:16 PM Jonathan Wakely <jwakely.gcc@xxxxxxxxx> wrote: > > On Wed, 29 May 2019 at 16:50, Johan Alfredsson wrote: > > > > Hi, > > > > I was under the impression that you could use std::conjunction to > > avoid instantiating templates for arguments following an argument the > > ::value of which would evaluate to something equivalent to 'false'. > > That's correct. > > > The code below seems to be an example of when this is not the case. > > I'm I misunderstanding something or is there a bug somewhere in gcc or > > libstdc++? > > I think this is a bug in your code. The is_barable_v<T> variable > template requires the instantiation of is_barable<T>::value > immediately, even if the conjunction instantiation doesn't need it.