<memory>
函数
addressof
获取对象的实际地址。
template <class T>
T* addressof(
T& value) noexcept; // before C++17
template <class T>
constexpr T* addressof(
T& value) noexcept; // C++17
template <class T>
const T* addressof(
const T&& value) = delete; // C++17
参数
value
要获取其实际地址的对象或函数。
返回值
由 value
引用的对象或函数的实际地址,即使存在重载的 operator&()
,情况也不例外。
备注
align
将给定大小的存储(通过给定对齐规范对齐)放入给定存储的第一个可能地址。
void* align(
size_t alignment, // input
size_t size, // input
void*& ptr, // input/output
size_t& space // input/output
);
参数
alignment
要尝试的对齐边界。
size
对齐存储的大小(以字节为单位)。
ptr
要使用的可用连续存储池的起始地址。 此参数还用作输出参数,如果对齐成功,将设置为包含新的起始地址。 如果 align()
不成功,则不修改此参数。
space
供 align()
用于创建对齐存储的总空间。 此参数还是输出参数,并包含存储缓冲区中在减去对齐存储和任何关联系统开销后剩余的调整空间。
如果 align()
不成功,则不修改此参数。
返回值
如果请求的对齐缓冲区无法放入可用空间,则返回 NULL
指针;否则返回 ptr
的新值。
备注
通过修改的 ptr
和 space
参数,可以使用不同的 align()
值和 alignment
值,对同一缓冲区重复调用 size
。 下面的代码片段演示 align()
的一种用法。
#include <type_traits> // std::alignment_of()
#include <memory>
//...
char buffer[256]; // for simplicity
size_t alignment = std::alignment_of<int>::value;
void * ptr = buffer;
std::size_t space = sizeof(buffer); // Be sure this results in the true size of your buffer
while (std::align(alignment, sizeof(MyObj), ptr, space)) {
// You now have storage the size of MyObj, starting at ptr, aligned on
// int boundary. Use it here if you like, or save off the starting address
// contained in ptr for later use.
// ...
// Last, move starting pointer and decrease available space before
// the while loop restarts.
ptr = reinterpret_cast<char*>(ptr) + sizeof(MyObj);
space -= sizeof(MyObj);
}
// At this point, align() has returned a null pointer, signaling it is not
// possible to allow more aligned storage in this buffer.
allocate_shared
创建指向对象的 shared_ptr
,这些对象通过指定分配器针对给定类型分配和构造。 返回 shared_ptr
。
template <class T, class Allocator, class... Args>
shared_ptr<T> allocate_shared(
Allocator alloc,
Args&&... args);
参数
alloc
用于创建对象的分配器。
args
成为对象的零个或更多自变量。
注解
此函数创建对象 shared_ptr<T>
,此对象为指向 T(args...)
的指针,通过 alloc
分配和构造。
atomic_compare_exchange_strong
template<class T>
bool atomic_compare_exchange_strong(
shared_ptr<T>* u,
shared_ptr<T>* v,
shared_ptr<T> w);
atomic_compare_exchange_weak
template<class T>
bool atomic_compare_exchange_weak(
shared_ptr<T>* u,
shared_ptr<T>* v,
shared_ptr<T> w);
atomic_compare_exchange_strong_explicit
template<class T>
bool atomic_compare_exchange_strong_explicit(
shared_ptr<T>* u,
shared_ptr<T>* v,
shared_ptr<T> w,
memory_order success,
memory_order failure);
atomic_compare_exchange_weak_explicit
template<class T>
bool atomic_compare_exchange_weak_explicit(
shared_ptr<T>* u,
shared_ptr<T>* v,
shared_ptr<T> w,
memory_order success,
memory_order failure);
atomic_exchange
template<class T>
shared_ptr<T> atomic_exchange(
shared_ptr<T>* u,
shared_ptr<T> r);
atomic_exchange_explicit
template<class T>
shared_ptr<T> atomic_exchange_explicit(
shared_ptr<T>* u,
shared_ptr<T> r,
memory_order mo);
atomic_is_lock_free
template<class T>
bool atomic_is_lock_free(
const shared_ptr<T>* u);
atomic_load
template<class T>
shared_ptr<T> atomic_load(
const shared_ptr<T>* u);
atomic_load_explicit
template<class T>
shared_ptr<T> atomic_load_explicit(
const shared_ptr<T>* u,
memory_order mo);
atomic_store
template<class T>
void atomic_store(
shared_ptr<T>* u,
shared_ptr<T> r);
atomic_store_explicit
template<class T>
void atomic_store_explicit(
shared_ptr<T>* u,
shared_ptr<T> r,
memory_order mo);
const_pointer_cast
常量强制转换为 shared_ptr
。
template <class T, class Other>
shared_ptr<T> const_pointer_cast(
const shared_ptr<Other>& sp) noexcept;
template <class T, class Other>
shared_ptr<T> const_pointer_cast(
shared_ptr<Other>&& sp) noexcept;
参数
T
由返回的共享指针控制的类型。
Other
由自变量共享指针控制的类型。
sp
自变量共享指针。
注解
如果 const_cast<T*>(sp.get())
返回一个 null 指针,则模板函数将返回空 shared_ptr
对象;否则它将返回 shared_ptr<T>
对象,该对象具有由 sp
拥有的资源。 表达式 const_cast<T*>(sp.get())
必须有效。
示例
// std__memory__const_pointer_cast.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp0(new int);
std::shared_ptr<const int> sp1 =
std::const_pointer_cast<const int>(sp0);
*sp0 = 3;
std::cout << "sp1 == " << *sp1 << std::endl;
return (0);
}
sp1 == 3
declare_no_pointers
通知垃圾回收器:通过基地址指针和块大小而定义的内存块中的字符不包含可跟踪的指针。
void declare_no_pointers(
char* ptr,
size_t size);
参数
ptr
第一个字符的地址,该字符不再包含可跟踪的指针。
size
块的大小,该块以不包含可跟踪的指针的 ptr
开始。
备注
该函数告知任何垃圾回收器,范围 [ptr, ptr + size)
内的地址不再包含可跟踪的指针。 (不得取消引用指向已分配存储的任何指针,除非使其可访问。)
declare_reachable
通知垃圾回收器:所指示的地址属于分配的存储并可到达。
void declare_reachable(
void* ptr);
参数
ptr
指向可访问、已分配且有效的存储区域的指针。
备注
如果 ptr
不为 null,则该函数将通知任何垃圾回收器现在可访问 ptr
,即,它指向有效的已分配存储。
default_delete
删除使用 operator new
分配的对象。 适合与 unique_ptr
一起使用。
struct default_delete
{
constexpr default_delete() noexcept = default;
template <class Other, class = typename enable_if<is_convertible<Other*, T*>::value, void>::type>>
default_delete(const default_delete<Other>&) noexcept;
void operator()(T* ptr) const noexcept;
};
参数
ptr
指向要删除的对象的指针。
Other
要删除的数组中的元素类型。
备注
此类模板描述一个删除器,它删除使用 operator new
分配的标量对象,适合与 unique_ptr
类模板一起使用。 它还具有显式专用化 default_delete<T[]>
。
destroy_at
template <class T>
void destroy_at(
T* location);
与 location->~T()
相同。
destroy
template <class ForwardIterator>
void destroy(
ForwardIterator first,
ForwardIterator last);
等同于:
for (; first != last; ++first)
destroy_at(addressof(*first));
destroy_n
template <class ForwardIterator, class Size>
ForwardIterator destroy_n(
ForwardIterator first,
Size count);
等同于:
for (; count > 0; (void)++first, --count)
destroy_at(addressof(*first));
return first;
dynamic_pointer_cast
动态强制转换为 shared_ptr
。
template <class T, class Other>
shared_ptr<T> dynamic_pointer_cast(
const shared_ptr<Other>& sp) noexcept;
template <class T, class Other>
shared_ptr<T> dynamic_pointer_cast(
shared_ptr<Other>&& sp) noexcept;
参数
T
由返回的共享指针控制的类型。
Other
由自变量共享指针控制的类型。
sp
自变量共享指针。
注解
如果 dynamic_cast<T*>(sp.get())
返回一个 null 指针,则模板函数将返回空 shared_ptr
对象;否则它将返回 shared_ptr<T>
对象,该对象具有由 sp
拥有的资源。 表达式 dynamic_cast<T*>(sp.get())
必须有效。
示例
// std__memory__dynamic_pointer_cast.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
struct base
{
virtual ~base() {}
int value;
};
struct derived
: public base
{
};
int main()
{
std::shared_ptr<base> sp0(new derived);
std::shared_ptr<derived> sp1 =
std::dynamic_pointer_cast<derived>(sp0);
sp0->value = 3;
std::cout << "sp1->value == " << sp1->value << std::endl;
return (0);
}
sp1->value == 3
get_deleter
从 shared_ptr
获取删除器。
template <class Deleter, class T>
Deleter* get_deleter(
const shared_ptr<T>& sp) noexcept;
参数
Deleter
删除器的类型。
T
由共享指针控制的类型。
sp
共享的指针。
备注
该模板函数返回一个指向 Deleter
类型的删除器的指针,该删除器属于 shared_ptr
对象 sp
。 如果 sp
没有删除器,或如果其删除器的类型不是 Deleter
,则该函数将返回 0。
示例
// std__memory__get_deleter.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
struct base
{
int value;
};
struct deleter
{
void operator()(base *pb)
{
delete pb;
}
};
int main()
{
std::shared_ptr<base> sp0(new base);
sp0->value = 3;
std::cout << "get_deleter(sp0) != 0 == " << std::boolalpha
<< (std::get_deleter<deleter>(sp0) != 0) << std::endl;
std::shared_ptr<base> sp1(new base, deleter());
sp0->value = 3;
std::cout << "get_deleter(sp1) != 0 == " << std::boolalpha
<< (std::get_deleter<deleter>(sp1) != 0) << std::endl;
return (0);
}
get_deleter(sp0) != 0 == false
get_deleter(sp1) != 0 == true
get_pointer_safety
返回任意垃圾回收器所采用的指针安全类型。
pointer_safety get_pointer_safety() noexcept;
备注
该函数返回任何自动垃圾回收器所采用的指针安全类型。
get_temporary_buffer
为不超过指定元素数量的元素序列分配临时存储。
template <class T>
pair<T *, ptrdiff_t> get_temporary_buffer(
ptrdiff_t count);
参数
count
所请求的、要为其分配内存的元素的最大数目。
返回值
一个 pair
,其第一个组件是一个指向已分配内存的指针,其第二个组件提供缓冲区的大小,指示它可以存储的元素的最大数目。
注解
该函数发出内存请求,该请求可能不会成功。 如果没有分配缓冲区,则该函数将返回一个 pair,其第二个组件等于零,第一个组件等于空指针。
仅对临时内存使用此函数。
示例
// memory_get_temp_buf.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
using namespace std;
int main( )
{
// Create an array of ints
int intArray [] = { 10, 20, 30, 40, 100, 200, 300, 1000, 2000 };
int count = sizeof ( intArray ) / sizeof ( int );
cout << "The number of integers in the array is: "
<< count << "." << endl;
pair<int *, ptrdiff_t> resultPair;
resultPair = get_temporary_buffer<int>( count );
cout << "The number of elements that the allocated memory\n"
<< "could store is given by: resultPair.second = "
<< resultPair.second << "." << endl;
}
The number of integers in the array is: 9.
The number of elements that the allocated memory
could store is given by: resultPair.second = 9.
make_shared
创建并返回指向分配对象的 shared_ptr
,这些对象是通过使用默认分配器从零个或多个参数构造的。 分配并构造指定类型的对象和shared_ptr
来管理对象的共享所有权,并返回shared_ptr
。
template <class T, class... Args>
shared_ptr<T> make_shared(
Args&&... args);
参数
args
零个或多个构造函数参数。 函数根据所提供的自变量来推断要调用的构造函数重载。
备注
使用make_shared
作为创建对象的简单、更高效的方法,以及一个shared_ptr
来同时管理对对象的共享访问。 在语义上,这两个语句是等效的:
auto sp = std::shared_ptr<Example>(new Example(argument));
auto msp = std::make_shared<Example>(argument);
但是,第一条语句进行了两个分配,如果在shared_ptr
对象的分配成功后,Example
的分配失败,则未命名的Example
对象将被泄漏。 使用make_shared
的语句更简单,因为只涉及到一个函数调用。 这样会更有效,因为库可能会对对象和智能指针进行一个分配。 此函数速度更快,并且产生的内存碎片更少,并且除了另一个以外,这个资源分配不可能出现异常。 通过使引用对象和更新智能指针中的引用计数的代码具有的更好的地址来提高性能。
如果你不需要对象的共享访问权限,请考虑使用 make_unique
。 如果需要为对象指定自定义的分配器,请使用 allocate_shared
。 如果对象需要自定义删除器,则不能使用 make_shared
,因为无法将删除器作为参数传递。
以下示例演示如何通过调用特定构造函数重载来创建指向类型的共享指针。
示例
// stl_make_shared.cpp
// Compile by using: cl /W4 /EHsc stl_make_shared.cpp
#include <iostream>
#include <string>
#include <memory>
#include <vector>
class Song {
public:
std::wstring title_;
std::wstring artist_;
Song(std::wstring title, std::wstring artist) : title_(title), artist_(artist) {}
Song(std::wstring title) : title_(title), artist_(L"Unknown") {}
};
void CreateSharedPointers()
{
// Okay, but less efficient to have separate allocations for
// Song object and shared_ptr control block.
auto song = new Song(L"Ode to Joy", L"Beethoven");
std::shared_ptr<Song> sp0(song);
// Use make_shared function when possible. Memory for control block
// and Song object are allocated in the same call:
auto sp1 = std::make_shared<Song>(L"Yesterday", L"The Beatles");
auto sp2 = std::make_shared<Song>(L"Blackbird", L"The Beatles");
// make_shared infers which constructor to use based on the arguments.
auto sp3 = std::make_shared<Song>(L"Greensleeves");
// The playlist vector makes copies of the shared_ptr pointers.
std::vector<std::shared_ptr<Song>> playlist;
playlist.push_back(sp0);
playlist.push_back(sp1);
playlist.push_back(sp2);
playlist.push_back(sp3);
playlist.push_back(sp1);
playlist.push_back(sp2);
for (auto&& sp : playlist)
{
std::wcout << L"Playing " << sp->title_ <<
L" by " << sp->artist_ << L", use count: " <<
sp.use_count() << std::endl;
}
}
int main()
{
CreateSharedPointers();
}
此示例产生以下输出:
Playing Ode to Joy by Beethoven, use count: 2
Playing Yesterday by The Beatles, use count: 3
Playing Blackbird by The Beatles, use count: 3
Playing Greensleeves by Unknown, use count: 2
Playing Yesterday by The Beatles, use count: 3
Playing Blackbird by The Beatles, use count: 3
make_unique
创建 unique_ptr
并将其返回到指定类型的对象,该对象通过指定的参数进行构造。
// make_unique<T>
template <class T, class... Args>
unique_ptr<T> make_unique(Args&&... args);
// make_unique<T[]>
template <class T>
unique_ptr<T> make_unique(size_t size);
// make_unique<T[N]> disallowed
template <class T, class... Args>
/* unspecified */ make_unique(Args&&...) = delete;
参数
T
unique_ptr
将指向的对象的类型。
Args
args
指定的构造函数自变量的类型。
args
要传递到 T
类型对象的构造函数的自变量。
elements
类型 T
的元素的数组。
size
新数组中要为其分配空间的元素的数目。
备注
第一个重载用于单个对象。 对数组调用第二个重载。 第三个重载阻止在类型参数 (make_unique<T[N]>
) 中指定数组大小;当前标准不支持这种构造。 当使用 make_unique
将 unique_ptr
创建到数组时,必须分别初始化数组元素。 与其使用此重载,也许不如使用 std::vector
。
由于谨慎实现 make_unique
以获得异常安全,因此建议您使用 make_unique
而不是直接调用 unique_ptr
构造函数。
示例
下面的示例说明如何使用 make_unique
。 有关更多示例,请参阅如何:创建和使用 unique_ptr 实例。
class Animal
{
private:
std::wstring genus;
std::wstring species;
int age;
double weight;
public:
Animal(const wstring&, const wstring&, int, double){/*...*/ }
Animal(){}
};
void MakeAnimals()
{
// Use the Animal default constructor.
unique_ptr<Animal> p1 = make_unique<Animal>();
// Use the constructor that matches these arguments
auto p2 = make_unique<Animal>(L"Felis", L"Catus", 12, 16.5);
// Create a unique_ptr to an array of 5 Animals
unique_ptr<Animal[]> p3 = make_unique<Animal[]>(5);
// Initialize the elements
p3[0] = Animal(L"Rattus", L"norvegicus", 3, 2.1);
p3[1] = Animal(L"Corynorhinus", L"townsendii", 4, 1.08);
// auto p4 = p2; //C2280
vector<unique_ptr<Animal>> vec;
// vec.push_back(p2); //C2280
// vector<unique_ptr<Animal>> vec2 = vec; // C2280
// OK. p2 no longer points to anything
vec.push_back(std::move(p2));
// unique_ptr overloads operator bool
wcout << boolalpha << (p2 == false) << endl; // Prints "true"
// OK but now you have two pointers to the same memory location
Animal* pAnimal = p2.get();
// OK. p2 no longer points to anything
Animal* p5 = p2.release();
}
如果您收到与 unique_ptr
有关的错误 C2280,则几乎可以肯定是因为您尝试调用其副本构造函数(此函数是一个已删除的函数)。
owner_less
允许对共享指针和弱指针进行基于所有权的混合比较。 如果成员函数 owner_before
将左侧参数排在右侧参数前面,则返回 true
。
template <class T>
struct owner_less; // not defined
template <class T>
struct owner_less<shared_ptr<T>>
{
bool operator()(
const shared_ptr<T>& left,
const shared_ptr<T>& right) const noexcept;
bool operator()(
const shared_ptr<T>& left,
const weak_ptr<T>& right) const noexcept;
bool operator()(
const weak_ptr<T>& left,
const shared_ptr<T>& right) const noexcept;
};
template <class T>
struct owner_less<weak_ptr<T>>
bool operator()(
const weak_ptr<T>& left,
const weak_ptr<T>& right) const noexcept;
bool operator()(
const weak_ptr<T>& left,
const shared_ptr<T>& right) const noexcept;
bool operator()(
const shared_ptr<T>& left,
const weak_ptr<T>& right) const noexcept;
};
template<> struct owner_less<void>
{
template<class T, class U>
bool operator()(
const shared_ptr<T>& left,
const shared_ptr<U>& right) const noexcept;
template<class T, class U>
bool operator()(
const shared_ptr<T>& left,
const weak_ptr<U>& right) const noexcept;
template<class T, class U>
bool operator()(
const weak_ptr<T>& left,
const shared_ptr<U>& right) const noexcept;
template<class T, class U>
bool operator()(
const weak_ptr<T>& left,
const weak_ptr<U>& right) const noexcept;
};
参数
left
共享指针或弱指针。
right
共享指针或弱指针。
注解
该类模板将其所有成员运算符都定义为返回 left.owner_before(right)
。
reinterpret_pointer_cast
使用强制转换从现有共享指针创建新的 shared_ptr
。
template<class T, class U>
shared_ptr<T> reinterpret_pointer_cast(
const shared_ptr<U>& ptr) noexcept;
template<class T, class U>
shared_ptr<T> reinterpret_pointer_cast(
shared_ptr<U>&& ptr) noexcept;
参数
ptr
对 shared_ptr<U>
的引用。
注解
如果 ptr
为空,则新的 shared_ptr
也为空,否则它与 ptr
共享所有权。 新的共享指针是 reinterpret_cast<Y*>(ptr.get())
的计算结果,其中 Y
是 typename std::shared_ptr<T>::element_type
。 如果 reinterpret_cast<T*>((U*)nullptr)
格式不当,则行为是未定义的。
采用 lvalue 引用的模板函数是 C++17 中的新增功能。 采用 rvalue 引用的模板函数是 C++20 中的新增功能。
return_temporary_buffer
对使用 get_temporary_buffer
模板函数分配的临时内存执行解除分配。
template <class T>
void return_temporary_buffer(
T* buffer);
参数
buffer
指向要取消分配的内存的指针。
备注
仅对临时内存使用此函数。
示例
// memory_ret_temp_buf.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
using namespace std;
int main( )
{
// Create an array of ints
int intArray [] = { 10, 20, 30, 40, 100, 200, 300 };
int count = sizeof ( intArray ) / sizeof ( int );
cout << "The number of integers in the array is: "
<< count << "." << endl;
pair<int *, ptrdiff_t> resultPair;
resultPair = get_temporary_buffer<int>( count );
cout << "The number of elements that the allocated memory\n"
<< " could store is given by: resultPair.second = "
<< resultPair.second << "." << endl;
int* tempBuffer = resultPair.first;
// Deallocates memory allocated with get_temporary_buffer
return_temporary_buffer( tempBuffer );
}
The number of integers in the array is: 7.
The number of elements that the allocated memory
could store is given by: resultPair.second = 7.
static_pointer_cast
静态强制转换为 shared_ptr
。
template <class T, class Other>
shared_ptr<T> static_pointer_cast(
const shared_ptr<Other>& sp) noexcept;
template <class T, class Other>
shared_ptr<T> static_pointer_cast(
shared_ptr<Other>&& sp) noexcept;
参数
T
由返回的共享指针控制的类型。
Other
由自变量共享指针控制的类型。
sp
自变量共享指针。
备注
如果 sp
是一个空 shared_ptr
对象,则模板函数将返回空 shared_ptr
对象;否则它将返回 shared_ptr<T>
对象,该对象具有由 sp
拥有的资源。 表达式 static_cast<T*>(sp.get())
必须有效。
示例
// std__memory__static_pointer_cast.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
struct base
{
int value;
};
struct derived
: public base
{
};
int main()
{
std::shared_ptr<base> sp0(new derived);
std::shared_ptr<derived> sp1 =
std::static_pointer_cast<derived>(sp0);
sp0->value = 3;
std::cout << "sp1->value == " << sp1->value << std::endl;
return (0);
}
sp1->value == 3
swap
交换两个 shared_ptr
、unique_ptr
或 weak_ptr
对象。
template <class T>
void swap(
shared_ptr<T>& left,
shared_ptr<T>& right) noexcept;
template <class T, class Deleter>
void swap(
unique_ptr<T, Deleter>& left,
unique_ptr<T, Deleter>& right) noexcept;
template <class T>
void swap(
weak_ptr<T>& left,
weak_ptr<T>& right) noexcept;
参数
T
由自变量指针控制的类型。
Deleter
唯一指针类型的删除器。
left
左指针。
right
右指针。
备注
模板函数调用 left.swap(right)
。
示例
// std__memory__swap.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp1(new int(5));
std::shared_ptr<int> sp2(new int(10));
std::cout << "*sp1 == " << *sp1 << std::endl;
sp1.swap(sp2);
std::cout << "*sp1 == " << *sp1 << std::endl;
swap(sp1, sp2);
std::cout << "*sp1 == " << *sp1 << std::endl;
std::cout << std::endl;
std::weak_ptr<int> wp1(sp1);
std::weak_ptr<int> wp2(sp2);
std::cout << "*wp1 == " << *wp1.lock() << std::endl;
wp1.swap(wp2);
std::cout << "*wp1 == " << *wp1.lock() << std::endl;
swap(wp1, wp2);
std::cout << "*wp1 == " << *wp1.lock() << std::endl;
return (0);
}
*sp1 == 5
*sp1 == 10
*sp1 == 5
*wp1 == 5
*wp1 == 10
*wp1 == 5
undeclare_no_pointers
通知垃圾回收器:通过基地址指针和块大小而定义的内存块中的字符现在可包含可跟踪的指针。
void undeclare_no_pointers(
char* ptr,
size_t size);
参数
ptr
指向先前使用 declare_no_pointers
标记的内存地址的指针。
size
内存范围内的字节数。 此值必须等于 declare_no_pointers
调用中使用的数字。
备注
该函数告知任何垃圾回收器,地址范围 [ptr, ptr + size)
现在可能包含可跟踪的指针。
undeclare_reachable
撤销指定的内存位置的可访问性声明。
template <class T>
T *undeclare_reachable(
T* ptr);
参数
ptr
指向先前使用 declare_reachable
标记的内存地址的指针。
备注
如果 ptr
不是 nullptr
,则该函数会告知任何垃圾回收器不再可访问 ptr
。 它返回一个比较结果等于 ptr
的安全派生指针。
uninitialized_copy
将指定源范围中的对象复制到未初始化的目标范围。
template <class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_copy(
InputIterator first,
InputIterator last,
ForwardIterator dest);
template <class ExecutionPolicy, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_copy(
ExecutionPolicy&& policy,
InputIterator first,
InputIterator last,
ForwardIterator dest);
参数
policy
要使用的执行策略。
first
确定源范围中第一个元素的地址的输入迭代器。
last
确定源范围中最后一个元素的地址的输入迭代器。
dest
确定目标范围中第一个元素的地址的前向迭代器。
返回值
确定超出目标范围的第一个位置的地址的前向迭代器,除非源范围为空。
备注
该算法可将内存分配与对象构造分离开。
该模板函数有效执行以下操作:
while (first != last)
{
new (static_cast<void*>(&* dest++))
typename iterator_traits<InputIterator>::value_type(*first++);
}
return dest;
除非代码引发异常。 在这种情况下,所有构造的对象将销毁,并重新引发异常。
具有执行策略的重载是 C++17 中的新增功能。
示例
// memory_uninit_copy.cpp
// compile with: /EHsc /W3
#include <memory>
#include <iostream>
using namespace std;
class Integer
{
public:
Integer(int x) : value(x) {}
int get() { return value; }
private:
int value;
};
int main()
{
int Array[] = { 10, 20, 30, 40 };
const int N = sizeof(Array) / sizeof(int);
cout << "The initialized Array contains " << N << " elements: ";
for (int i = 0; i < N; i++)
{
cout << " " << Array[i];
}
cout << endl;
Integer* ArrayPtr = (Integer*)malloc(N * sizeof(int));
Integer* LArrayPtr = uninitialized_copy(
Array, Array + N, ArrayPtr); // C4996
cout << "Address of position after the last element in the array is: "
<< &Array[0] + N << endl;
cout << "The iterator returned by uninitialized_copy addresses: "
<< (void*)LArrayPtr << endl;
cout << "The address just beyond the last copied element is: "
<< (void*)(ArrayPtr + N) << endl;
if ((&Array[0] + N) == (void*)LArrayPtr)
cout << "The return value is an iterator "
<< "pointing just beyond the original array." << endl;
else
cout << "The return value is an iterator "
<< "not pointing just beyond the original array." << endl;
if ((void*)LArrayPtr == (void*)(ArrayPtr + N))
cout << "The return value is an iterator "
<< "pointing just beyond the copied array." << endl;
else
cout << "The return value is an iterator "
<< "not pointing just beyond the copied array." << endl;
free(ArrayPtr);
cout << "Note that the exact addresses returned will vary\n"
<< "with the memory allocation in individual computers."
<< endl;
}
uninitialized_copy_n
创建来自输入迭代器的指定数量的元素的副本。 副本放置在向前迭代器中。
template <class InputIterator, class Size, class ForwardIterator>
ForwardIterator uninitialized_copy_n(
InputIterator first,
Size count,
ForwardIterator dest);
template <class ExecutionPolicy, class InputIterator, class Size, class ForwardIterator>
ForwardIterator uninitialized_copy_n(
ExecutionPolicy&& policy,
InputIterator first,
Size count,
ForwardIterator dest);
参数
policy
要使用的执行策略。
first
引用要复制的对象的输入迭代器。
count
指定复制对象的次数的带符号或无符号整数类型。
dest
引用新副本所在位置的向前迭代器。
返回值
发现超出目标的第一个位置的向前迭代器。 如果源范围为空,迭代器将发现 first
。
备注
模板函数有效执行以下代码:
for (; 0 < count; --count)
new (static_cast<void*>(&* dest++))
typename iterator_traits<InputIterator>::value_type(*first++);
return dest;
除非代码引发异常。 在这种情况下,所有构造的对象将销毁,并重新引发异常。
具有执行策略的重载是 C++17 中的新增功能。
uninitialized_default_construct
默认值会在指定范围内构造迭代器对象的 value_type
。
template <class ForwardIterator>
void uninitialized_default_construct(
ForwardIterator first,
ForwardIterator last);
template <class ExecutionPolicy, class ForwardIterator>
void uninitialized_default_construct(
ExecutionPolicy&& policy,
ForwardIterator first,
ForwardIterator last);
参数
policy
要使用的执行策略。
first
一个用于寻址范围内要构造的第一个元素的迭代器。
last
一个用于寻址范围内要构造的最后一个元素之后的一个元素的迭代器。
备注
没有执行策略的版本实际上等同于:
for (; first != last; ++first)
::new (static_cast<void*>(addressof(*first)))
typename iterator_traits<ForwardIterator>::value_type;
如果引发异常,则按未指定的顺序销毁先前构造的对象。
具有执行策略的版本的结果相同,但根据指定的 policy
执行。
这些函数是 C++17 中的新增功能。
uninitialized_default_construct_n
默认值会构造迭代器对象的指定数量的 value_type
,从指定的位置开始。
template <class ForwardIterator, class Size>
ForwardIterator uninitialized_default_construct_n(
ForwardIterator first,
Size count);
template <class ExecutionPolicy, class ForwardIterator, class Size>
ForwardIterator uninitialized_default_construct_n(
ExecutionPolicy&& policy,
ForwardIterator first,
Size count);
参数
policy
要使用的执行策略。
first
一个用于寻址目标范围内要构造的第一个元素的迭代器。
count
目标范围内要构造的元素计数。
返回值
确定超出目标范围的第一个位置的地址的前向迭代器,除非源范围为空。
备注
没有执行策略的版本实际上等同于:
for (; count>0; (void)++first, --count)
::new (static_cast<void*>(addressof(*first)))
typename iterator_traits<ForwardIterator>::value_type;
return first;
如果引发异常,则按未指定的顺序销毁先前构造的对象。
具有执行策略的版本的结果相同,但根据指定的 policy
执行。
这些函数是 C++17 中的新增功能。
uninitialized_fill
将具有指定值的对象复制到未初始化的目标范围。
template <class ForwardIterator, class T>
void uninitialized_fill(
ForwardIterator first,
ForwardIterator last,
const T& value);
template <class ExecutionPolicy, class ForwardIterator, class T>
void uninitialized_fill(
ExecutionPolicy&& policy,
ForwardIterator first,
ForwardIterator last,
const T& value);
参数
policy
要使用的执行策略。
first
一个用于寻址目标范围内要初始化的第一个元素的向前迭代器。
last
一个用于寻址目标范围内要初始化的最后一个元素的向前迭代器。
value
用于初始化目标范围的值。
备注
该算法可将内存分配与对象构造分离开。
该模板函数有效执行以下操作:
while (first != last)
new (static_cast<void*>(&* first ++))
typename iterator_traits<ForwardIterator>::value_type (value);
除非代码引发异常。 在这种情况下,所有构造的对象将销毁,并重新引发异常。
具有执行策略的重载是 C++17 中的新增功能。
示例
// memory_uninit_fill.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
using namespace std;
class Integer
{
public:
// No default constructor
Integer( int x ) : value( x ) {}
int get() { return value; }
private:
int value;
};
int main()
{
const int N = 10;
Integer value ( 25 );
Integer* Array = ( Integer* ) malloc( N * sizeof( int ) );
uninitialized_fill( Array, Array + N, value );
cout << "The initialized Array contains: ";
for ( int i = 0; i < N; i++ )
{
cout << Array[ i ].get() << " ";
}
cout << endl;
}
The initialized Array contains: 25 25 25 25 25 25 25 25 25 25
uninitialized_fill_n
将具有指定值的对象复制到未初始化目标范围的指定数量的元素。
template <class ForwardIterator, class Size, class T>
ForwardIterator uninitialized_fill_n(
ForwardIterator first,
Size count,
const T& value);
template <class ExecutionPolicy, class ForwardIterator, class Size, class T>
ForwardIterator uninitialized_fill_n(
ExecutionPolicy&& policy,
ForwardIterator first,
Size count,
const T& value);
参数
policy
要使用的执行策略。
first
一个用于寻址目标范围内要初始化的第一个元素的向前迭代器。
count
要初始化的元素数。
value
用于初始化目标范围的值。
备注
该算法可将内存分配与对象构造分离开。
该模板函数有效执行以下操作:
while (0 < count--)
new (static_cast<void*>(&* first++))
typename iterator_traits<ForwardIterator>::value_type(value);
return first;
除非代码引发异常。 在这种情况下,所有构造的对象将销毁,并重新引发异常。
具有执行策略的重载是 C++17 中的新增功能。
示例
// memory_uninit_fill_n.cpp
// compile with: /EHsc /W3
#include <memory>
#include <iostream>
using namespace std;
class Integer
{
public:
// No default constructor
Integer( int x ) : value( x ) {}
int get() { return value; }
private:
int value;
};
int main()
{
const int N = 10;
Integer value( 60 );
Integer* Array = ( Integer* ) malloc( N * sizeof( int ) );
uninitialized_fill_n( Array, N, value ); // C4996
cout << "The uninitialized Array contains: ";
for ( int i = 0; i < N; i++ )
cout << Array[ i ].get() << " ";
}
uninitialized_move
将元素从源范围移到未初始化的目标内存区。
template <class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_move(
InputIterator first,
InputIterator last,
ForwardIterator dest);
template <class ExecutionPolicy, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_move(
ExecutionPolicy&& policy,
InputIterator first,
InputIterator last,
ForwardIterator dest);
参数
policy
要使用的执行策略。
first
一个用于寻址源范围内要移动的第一个元素的输入迭代器。
last
一个用于寻址源范围内要移动的最后一个元素之后的一个元素的输入迭代器。
dest
目标范围的起点。
备注
没有执行策略的版本实际上等同于:
for (; first != last; (void)++dest, ++first)
::new (static_cast<void*>(addressof(*dest)))
typename iterator_traits<ForwardIterator>::value_type(std::move(*first));
return dest;
如果引发异常,则源范围内的某些对象可能会保持有效但未指定的状态。 先前构造的对象将按未指定的顺序销毁。
具有执行策略的版本的结果相同,但根据指定的 policy
执行。
这些函数是 C++17 中的新增功能。
uninitialized_move_n
将指定数量的元素从源范围移到未初始化的目标内存区。
template <class InputIterator, class Size, class ForwardIterator>
pair<InputIterator, ForwardIterator> uninitialized_move_n(
InputIterator first,
Size count,
ForwardIterator dest);
template <class ExecutionPolicy, class InputIterator, class Size, class ForwardIterator>
pair<InputIterator, ForwardIterator> uninitialized_move_n(
ExecutionPolicy&& policy,
InputIterator first,
Size count,
ForwardIterator dest);
参数
policy
要使用的执行策略。
first
一个用于寻址源范围内要移动的第一个元素的输入迭代器。
count
源范围内要移动的元素数。
dest
目标范围的起点。
备注
没有执行策略的版本实际上等同于:
for (; count > 0; ++dest, (void) ++first, --count)
::new (static_cast<void*>(addressof(*dest)))
typename iterator_traits<ForwardIterator>::value_type(std::move(*first));
return {first, dest};
如果引发异常,则源范围内的某些对象可能会保持有效但未指定的状态。 先前构造的对象将按未指定的顺序销毁。
具有执行策略的版本的结果相同,但根据指定的 policy
执行。
这些函数是 C++17 中的新增功能。
uninitialized_value_construct
在指定的范围内通过值初始化构造迭代器对象的 value_type
。
template <class ForwardIterator>
void uninitialized_value_construct(
ForwardIterator first,
ForwardIterator last);
template <class ExecutionPolicy, class ForwardIterator>
void uninitialized_value_construct(
ExecutionPolicy&& policy,
ForwardIterator first,
ForwardIterator last);
参数
policy
要使用的执行策略。
first
一个用于寻址范围内要通过值初始化构造的第一个元素的迭代器。
last
一个用于寻址范围内要通过值初始化构造的最后一个元素之后的一个元素的迭代器。
备注
没有执行策略的版本实际上等同于:
for (; first != last; ++first)
::new (static_cast<void*>(addressof(*first)))
typename iterator_traits<ForwardIterator>::value_type();
如果引发异常,则按未指定的顺序销毁先前构造的对象。
具有执行策略的版本的结果相同,但根据指定的 policy
执行。
如果发生内存分配失败,则会引发 std::bad_alloc
异常。
这些函数是 C++17 中的新增功能。
uninitialized_value_construct_n
通过值初始化构造迭代器对象的指定数量的 value_type
,从指定的位置开始。
template <class ForwardIterator, class Size>
ForwardIterator uninitialized_value_construct_n(
ForwardIterator first,
Size count);
template <class ExecutionPolicy, class ForwardIterator, class Size>
ForwardIterator uninitialized_value_construct_n(
ExecutionPolicy&& policy,
ForwardIterator first,
Size count);
参数
policy
要使用的执行策略。
first
一个用于寻址目标范围内要构造的第一个元素的迭代器。
count
目标范围内要构造的元素计数。
注解
没有执行策略的版本实际上等同于:
for (; count > 0; (void)++first, --count)
::new (static_cast<void*>(addressof(*first)))
typename iterator_traits<ForwardIterator>::value_type();
return first;
如果引发异常,则按未指定的顺序销毁先前构造的对象。
具有执行策略的版本的结果相同,但根据指定的 policy
执行。
如果发生内存分配失败,则会引发 std::bad_alloc
异常。
这些函数是 C++17 中的新增功能。
uses_allocator_v
用于访问 uses_allocator
模板值的帮助器变量模板。
template <class T, class Alloc>
inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value;