C++ Coding Reference: Copy N values by using std::fill_n()

  • 时间:2020-09-17 11:25:43
  • 分类:网络文摘
  • 阅读:90 次

We talked about std::fill() that we can use to copy over a single value to a range [First, Last). If you know the number of elements you want to copy into, you can use the std::fill_n() instead. In the header xutility, the std::fill_n() using generic template definition is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
template<class _OutIt,
    class _Diff,
    class _Ty> inline
    _OutIt _Fill_n_unchecked2(_OutIt _Dest, _Diff _Count, const _Ty& _Val, true_type)
    {   // copy _Val _Count times through [_Dest, ...), memset optimization
    _CSTD memset(_Dest, static_cast<unsigned char>(_Val), static_cast<size_t>(_Count));
    return (_Dest + _Count);
    }
 
template<class _OutIt,
    class _Diff,
    class _Ty> inline
    _OutIt fill_n(_OutIt _Dest, _Diff _Count_raw, const _Ty& _Val)
    {   // copy _Val _Count times through [_Dest, ...)
    const _Algorithm_int_t<_Diff> _Count = _Count_raw;
    if (0 < _Count)
        {
        const auto _UDest = _Get_unwrapped_n(_Dest, _Count);
        _Seek_wrapped(_Dest,
            _Fill_n_unchecked2(_UDest, _Count, _Val, _Fill_memset_is_safe(_UDest, _Val)));
        }
 
    return (_Dest);
    }
template<class _OutIt,
	class _Diff,
	class _Ty> inline
	_OutIt _Fill_n_unchecked2(_OutIt _Dest, _Diff _Count, const _Ty& _Val, true_type)
	{	// copy _Val _Count times through [_Dest, ...), memset optimization
	_CSTD memset(_Dest, static_cast<unsigned char>(_Val), static_cast<size_t>(_Count));
	return (_Dest + _Count);
	}

template<class _OutIt,
	class _Diff,
	class _Ty> inline
	_OutIt fill_n(_OutIt _Dest, _Diff _Count_raw, const _Ty& _Val)
	{	// copy _Val _Count times through [_Dest, ...)
	const _Algorithm_int_t<_Diff> _Count = _Count_raw;
	if (0 < _Count)
		{
		const auto _UDest = _Get_unwrapped_n(_Dest, _Count);
		_Seek_wrapped(_Dest,
			_Fill_n_unchecked2(_UDest, _Count, _Val, _Fill_memset_is_safe(_UDest, _Val)));
		}

	return (_Dest);
	}

As we can see, it is based on memset.

Example Usages of std::fill_n()

The std::fill_n() takes three parameters: the destination, the count and the value to copy over, namely:

1
std::fill_n(destination, count, value);
std::fill_n(destination, count, value);

For example, using std::fill_n() to copy value of 3 into a static array (of integer) for the first 4 elements:

1
2
int nums[10];
std::fill_n(begin(nums), 4, 3); // nums is now [3, 3, 3, 3, .., .., ..]
int nums[10];
std::fill_n(begin(nums), 4, 3); // nums is now [3, 3, 3, 3, .., .., ..]

std::fill_n() takes generic types, thus, you can use it on array of chars:

1
2
char buf[6];
std::fill_n(begin(buf), 3, 'a'); // buf is ['a', 'a', 'a', .., ..]
char buf[6];
std::fill_n(begin(buf), 3, 'a'); // buf is ['a', 'a', 'a', .., ..]

You can also use std::fill_n() to copy over custom data type, for example, the following copies over 3 structs:

1
2
3
4
5
6
typedef struct {
    int x, y;
} data;
vector<data> arr(10);
data x = { 1, 2 };
std::fill_n(begin(arr), 3, x);
typedef struct {
	int x, y;
} data;
vector<data> arr(10);
data x = { 1, 2 };
std::fill_n(begin(arr), 3, x);

Similar to std::fill(), you would need to make sure the destination memory locations can be written to otherwise a runtime memory Access Violation could be expected.

–EOF (The Ultimate Computing & Technology Blog) —

推荐阅读:
The Git Pre-Commit Hook to Avoid Pushing Only Unit Tests In Node  How to Find the Most Common Word in a String with a Banned List?  How to Construct Minimum Spanning Tree using Kruskal or Breadth   Two Pointer and Sliding Window Algorithm to Find K-Length Substr  How to Get the Maximum Level Sum of a Binary Tree using Breadth   Compute the Minimum Costs to Connect the Sticks using Priority Q  Single-Row Keyboard Algorithms to Estimate the Finger Moving Tim  Bruteforce Algorithm to Find the Next Closet Time Reusing the Cu  The Overlapping Rectangles using CSS and Javascript  How to Count the Distinct Pairs using HashMap? 
评论列表
添加评论