Due to the "as-if" rule it is probably unreliable to try to view the compilation process to see where temporaries are created.
But reading the code (and coding) while keeping in mind the following paragraph of the standard may help in finding where temporaries are created or not, [class.temporary]/2
The materialization of a temporary object is generally delayed as long as possible in order to avoid creating unnecessary temporary objects. [ Note: Temporary objects are materialized:
when binding a reference to a prvalue ([dcl.init.ref], [expr.type.conv], [expr.dynamic.cast], [expr.static.cast], [expr.const.cast], [expr.cast]),
when performing member access on a class prvalue ([expr.ref], [expr.mptr.oper]),
when performing an array-to-pointer conversion or subscripting on an array prvalue,
when initializing an object of type std::initializer_list from a braced-init-list ([dcl.init.list]),
for certain unevaluated operands ([expr.typeid], [expr.sizeof]), and
when a prvalue appears as a discarded-value expression.
In this paragraph coming from the C++17 standard, the term prvalue has a new definition [basic.lval]/1:
A prvalue is an expression whose evaluation initializes an object or a bit-field, or computes the value of the operand of an operator, as specified by the context in which it appears.
And in the last standard (pre C++20), the paragraph [basic.lval] has been moved to Expressions [expr], so what we knew as value categories is evolving to become expression categories.