The easiest way to do this is with a 'numbers' table. A numbers table simply includes the numbers 1, 2, 3, 4 etc up to a large number - larger than you'll ever need. It may also include 0 if desired.
Note that a key part of a numbers table is a PRIMARY KEY (or at worst, a UNIQUE clustered index) on the numbers column. This means it is easy for SQL Server to identify the numbers it wants to use - otherwise it will do one or more table scans to perform the join.
If you have a numbers table, the simple thing to do is to join your original #temp table with the numbers table using inequalities - e.g., find all numbers that are >= the beginning value, and <= the ending value.
Below is an example, where #Nums is a numbers table.
create table #temp (id int, beg int, ending int);
insert into #temp values (1, 1, 5), (2, 2, 8), (3, 1, 3);
SELECT #temp.id, #Nums.n
FROM #temp
INNER JOIN #Nums ON #temp.beg <= #Nums.n AND #temp.ending >= #Nums.n
@Andre's answer above uses a numbers table as well - however it is created recursively.
To create a numbers table efficiently, here is one of the better methods (using cross-joins) - this creates a table with 100,000 rows from 0 to 99,999, and is easily expanded.
CREATE TABLE #Nums (n int PRIMARY KEY);
INSERT INTO #Nums (n)
SELECT a.n + b.n * 10 + c.n * 100 + d.n * 1000 + e.n * 10000
FROM (VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9)) AS a(n)
CROSS JOIN (VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9)) AS b(n)
CROSS JOIN (VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9)) AS c(n)
CROSS JOIN (VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9)) AS d(n)
CROSS JOIN (VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9)) AS e(n);