Good to see so many ways to skin this cat. Here's one using a CTE (you can also nest the query for more ANSI-ism, but I find CTEs great to avoid a lot of indenting and declaring things up front makes it pretty readable up top and down below):
WITH LastMeasurements AS (
SELECT [Town], MAX([Date]) AS LastMeasurementDate
FROM [Measurement]
GROUP BY [Town]
)
SELECT [Measurement].Town, [Measurement].[Date], [Measurement].Temp
FROM [Measurement]
INNER JOIN LastMeasurements
ON [Measurement].[Town] = LastMeasurements.[Town]
AND [Measurement].[Date] = LastMeasurements.LastMeasurementDate
What I like about the explicit seeking back technique is that it easily gives you access to all the information in the top row selected for the group and is very flexible in changing the grouping and low on repeating yourself.
The optimizer tends to perform these pretty quickly on SQL Server - like most solutions, if you have an index on Town, Date, Temp this will be covering and will run super fast. Even if it's just on Town, Date, the bulk of the work in the GROUP BY
can be done super fast anyway.