Difference between revisions of "cpp/memory/out ptr t"
m (→Notes: + feature test macro) |
(Links to the definitions of “program-defined type” and “program-defined specialization”.) |
||
(6 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
{{cpp/title|out_ptr_t}} | {{cpp/title|out_ptr_t}} | ||
{{cpp/memory/out_ptr_t/navbar}} | {{cpp/memory/out_ptr_t/navbar}} | ||
− | {{ddcl | header=memory | since=c++23 | | + | {{ddcl|header=memory|since=c++23| |
template< class Smart, class Pointer, class... Args > | template< class Smart, class Pointer, class... Args > | ||
class out_ptr_t; | class out_ptr_t; | ||
}} | }} | ||
− | {{tt|out_ptr_t}} is used to adapt types such as smart pointers for foreign functions that output their results via a {{ | + | {{tt|out_ptr_t}} is used to adapt types such as smart pointers for foreign functions that output their results via a {{tt|Pointer*}} (usually {{tt|T**}} for some object type {{tt|T}}) or {{c/core|void**}} parameter. |
− | {{tt|out_ptr_t}} captures additional arguments on construction, provides | + | {{tt|out_ptr_t}} captures additional arguments on construction, provides storage for the result to which such an aforementioned foreign function writes, and finally resets the adapted {{tt|Smart}} object with the result and the captured arguments when it is destroyed. |
{{tt|out_ptr_t}} behaves as if it holds following non-static data members: | {{tt|out_ptr_t}} behaves as if it holds following non-static data members: | ||
− | * a {{ | + | * a {{tt|Smart&}} reference, which is bound to the adapted object on construction, |
* for every {{tt|T}} in {{tt|Args...}}, a member of type {{tt|T}}, which is an argument captured on construction and used for resetting while destruction, and | * for every {{tt|T}} in {{tt|Args...}}, a member of type {{tt|T}}, which is an argument captured on construction and used for resetting while destruction, and | ||
− | * a member subobject that suitable for storing a {{tt|Pointer}} within it and providing a {{c|void*}} object, where the {{tt|Pointer}} or {{c|void*}} object is generally exposed to a foreign function for re-initialization. | + | * a member subobject that suitable for storing a {{tt|Pointer}} within it and providing a {{c/core|void*}} object, where the {{tt|Pointer}} or {{c/core|void*}} object is generally exposed to a foreign function for re-initialization. |
Users can control whether each argument for resetting is captured by copy or by reference, by specifying an object type or a reference type in {{tt|Args...}} respectively. | Users can control whether each argument for resetting is captured by copy or by reference, by specifying an object type or a reference type in {{tt|Args...}} respectively. | ||
Line 19: | Line 19: | ||
===Template parameters=== | ===Template parameters=== | ||
{{par begin}} | {{par begin}} | ||
− | {{par | Smart | the type of the object (typically a smart pointer) to adapt}} | + | {{par|Smart|the type of the object (typically a smart pointer) to adapt}} |
− | {{par | Pointer | type of the object (typically a raw pointer) to which a foreign function writes its result}} | + | {{par|Pointer|type of the object (typically a raw pointer) to which a foreign function writes its result}} |
− | {{par | Args... | type of captured arguments used for resetting the adapted object}} | + | {{par|Args...|type of captured arguments used for resetting the adapted object}} |
{{par hreq}} | {{par hreq}} | ||
− | {{par req named | Pointer | NullablePointer}} | + | {{par req named|Pointer|NullablePointer}} |
− | {{par req | The program is ill-formed if {{tt|Smart}} is a {{lc|std::shared_ptr}} specialization and {{c|1=sizeof...(Args) == 0}}.}} | + | {{par req|The program is ill-formed if {{tt|Smart}} is a {{lc|std::shared_ptr}} specialization and {{c|1=sizeof...(Args) == 0}}.}} |
{{par end}} | {{par end}} | ||
===Specializations=== | ===Specializations=== | ||
− | Unlike most class templates in the standard library, program-defined specializations of {{tt|out_ptr_t}} that depend on at least one | + | Unlike most class templates in the standard library, [[cpp/language/type#Program-defined type|program-defined specializations]] of {{tt|out_ptr_t}} that depend on at least one {{lsd|cpp/language/type#Program-defined type}} need not meet the requirements for the primary template. |
This license allows a program-defined specialization to expose the raw pointer stored within a non-standard smart pointer to foreign functions. | This license allows a program-defined specialization to expose the raw pointer stored within a non-standard smart pointer to foreign functions. | ||
Line 34: | Line 34: | ||
===Member functions=== | ===Member functions=== | ||
{{dsc begin}} | {{dsc begin}} | ||
− | {{dsc mem ctor | cpp/memory/out_ptr_t/out_ptr_t | notes={{mark c++23}} | constructs an {{tt|out_ptr_t}}}} | + | {{dsc mem ctor|cpp/memory/out_ptr_t/out_ptr_t|notes={{mark c++23}}|constructs an {{tt|out_ptr_t}}}} |
− | {{dsc mem fun | operator{{=}} | nolink=true | notes={{cmark deleted}}{{mark c++23}} | {{tt|out_ptr_t}} is not assignable}} | + | {{dsc mem fun|operator{{=}}|nolink=true|notes={{cmark deleted}}{{mark c++23}}|{{tt|out_ptr_t}} is not assignable}} |
− | {{dsc mem dtor | cpp/memory/out_ptr_t/~out_ptr_t | notes={{mark c++23}} | resets the adapted smart pointer}} | + | {{dsc mem dtor|cpp/memory/out_ptr_t/~out_ptr_t|notes={{mark c++23}}|resets the adapted smart pointer}} |
− | {{dsc mem fun | cpp/memory/out_ptr_t/operator ptr | title=operator Pointer*<br>operator void** | notes={{mark c++23}} | converts the {{tt|out_ptr_t}} to the address of the storage for output}} | + | {{dsc mem fun|cpp/memory/out_ptr_t/operator ptr|title=operator Pointer*<br>operator void**|notes={{mark c++23}}|converts the {{tt|out_ptr_t}} to the address of the storage for output}} |
{{dsc end}} | {{dsc end}} | ||
===Non-member functions=== | ===Non-member functions=== | ||
{{dsc begin}} | {{dsc begin}} | ||
− | {{dsc inc | cpp/memory/out_ptr_t/dsc out_ptr}} | + | {{dsc inc|cpp/memory/out_ptr_t/dsc out_ptr}} |
{{dsc end}} | {{dsc end}} | ||
Line 53: | Line 53: | ||
std::unique_ptr<T, D> up; | std::unique_ptr<T, D> up; | ||
− | if (int ec = foreign_setter(std::out_ptr(up)) | + | if (int ec = foreign_setter(std::out_ptr(up))) |
return ec; | return ec; | ||
− | |||
}} | }} | ||
is roughly equivalent to | is roughly equivalent to | ||
Line 65: | Line 64: | ||
int ec = foreign_setter(&raw_p); | int ec = foreign_setter(&raw_p); | ||
up.reset(raw_p); | up.reset(raw_p); | ||
− | if (ec != 0) | + | if (ec != 0) |
return ec; | return ec; | ||
− | |||
}} | }} | ||
− | It is not recommended to create an {{tt|out_ptr_t}} object of a | + | It is not recommended to create an {{tt|out_ptr_t}} object of a {{lt|cpp/language/storage duration}} other than automatic storage duration, because such code is likely to produce dangling references and result in undefined behavior on destruction. |
{{tt|out_ptr_t}} forbids the usage that would reset a {{lc|std::shared_ptr}} without specifying a deleter, because it would call {{lc|std::shared_ptr::reset}} and replace a custom deleter later. | {{tt|out_ptr_t}} forbids the usage that would reset a {{lc|std::shared_ptr}} without specifying a deleter, because it would call {{lc|std::shared_ptr::reset}} and replace a custom deleter later. | ||
− | Captured arguments are typically packed into a {{c|std::tuple<Args...>}}. Implementations may use different mechanism to provide the {{tt|Pointer}} or {{c|void*}} object they need hold. | + | Captured arguments are typically packed into a {{c/core|std::tuple<Args...>}}. Implementations may use different mechanism to provide the {{tt|Pointer}} or {{c/core|void*}} object they need hold. |
− | {{ | + | {{ftm begin|sort=yes}} |
+ | {{ftm|std=C++23|value=202106L|__cpp_lib_out_ptr|rowspan="2"|{{tt|std::out_ptr}}, {{lc|std::inout_ptr}}}} | ||
+ | {{ftm|std=C++26|value=202311L|-|freestanding {{tt|std::out_ptr}} and {{lc|std::inout_ptr}}}} | ||
+ | {{ftm end}} | ||
===Example=== | ===Example=== | ||
Line 83: | Line 84: | ||
===See also=== | ===See also=== | ||
{{dsc begin}} | {{dsc begin}} | ||
− | {{dsc inc | cpp/memory/dsc inout_ptr_t}} | + | {{dsc inc|cpp/memory/dsc inout_ptr_t}} |
− | {{dsc inc | cpp/memory/dsc unique_ptr}} | + | {{dsc inc|cpp/memory/dsc unique_ptr}} |
− | {{dsc inc | cpp/memory/dsc shared_ptr}} | + | {{dsc inc|cpp/memory/dsc shared_ptr}} |
{{dsc end}} | {{dsc end}} | ||
{{langlinks|es|ja|ru|zh}} | {{langlinks|es|ja|ru|zh}} |
Latest revision as of 18:03, 12 March 2024
Defined in header <memory>
|
||
template< class Smart, class Pointer, class... Args > class out_ptr_t; |
(since C++23) | |
out_ptr_t
is used to adapt types such as smart pointers for foreign functions that output their results via a Pointer*
(usually T**
for some object type T
) or void** parameter.
out_ptr_t
captures additional arguments on construction, provides storage for the result to which such an aforementioned foreign function writes, and finally resets the adapted Smart
object with the result and the captured arguments when it is destroyed.
out_ptr_t
behaves as if it holds following non-static data members:
- a
Smart&
reference, which is bound to the adapted object on construction, - for every
T
inArgs...
, a member of typeT
, which is an argument captured on construction and used for resetting while destruction, and - a member subobject that suitable for storing a
Pointer
within it and providing a void* object, where thePointer
or void* object is generally exposed to a foreign function for re-initialization.
Users can control whether each argument for resetting is captured by copy or by reference, by specifying an object type or a reference type in Args...
respectively.
Contents |
[edit] Template parameters
Smart | - | the type of the object (typically a smart pointer) to adapt |
Pointer | - | type of the object (typically a raw pointer) to which a foreign function writes its result |
Args... | - | type of captured arguments used for resetting the adapted object |
Type requirements | ||
-Pointer must meet the requirements of NullablePointer.
| ||
-The program is ill-formed if Smart is a std::shared_ptr specialization and sizeof...(Args) == 0.
|
[edit] Specializations
Unlike most class templates in the standard library, program-defined specializations of out_ptr_t
that depend on at least one program-defined type need not meet the requirements for the primary template.
This license allows a program-defined specialization to expose the raw pointer stored within a non-standard smart pointer to foreign functions.
[edit] Member functions
(C++23) |
constructs an out_ptr_t (public member function) |
operator= [deleted](C++23) |
out_ptr_t is not assignable (public member function) |
(C++23) |
resets the adapted smart pointer (public member function) |
converts the out_ptr_t to the address of the storage for output (public member function) |
[edit] Non-member functions
(C++23) |
creates an out_ptr_t with an associated smart pointer and resetting arguments (function template) |
[edit] Notes
out_ptr_t
expects that the foreign functions do not used the value of the pointed-to Pointer
, and only re-initialize it. The value of the smart pointer before adaption is not used.
The typical usage of out_ptr_t
is creating its temporary objects by std::out_ptr, which resets the adapted smart pointer immediately. E.g. given a setter function and a smart pointer of appropriate type declared with int foreign_setter(T**); and std::unique_ptr<T, D> up; respectively,
int foreign_setter(T**); std::unique_ptr<T, D> up; if (int ec = foreign_setter(std::out_ptr(up))) return ec;
is roughly equivalent to
int foreign_setter(T**); std::unique_ptr<T, D> up; T* raw_p{}; int ec = foreign_setter(&raw_p); up.reset(raw_p); if (ec != 0) return ec;
It is not recommended to create an out_ptr_t
object of a storage duration other than automatic storage duration, because such code is likely to produce dangling references and result in undefined behavior on destruction.
out_ptr_t
forbids the usage that would reset a std::shared_ptr without specifying a deleter, because it would call std::shared_ptr::reset and replace a custom deleter later.
Captured arguments are typically packed into a std::tuple<Args...>. Implementations may use different mechanism to provide the Pointer
or void* object they need hold.
Feature-test macro | Value | Std | Feature |
---|---|---|---|
__cpp_lib_out_ptr |
202106L | (C++23) | std::out_ptr , std::inout_ptr
|
202311L | (C++26) | freestanding std::out_ptr and std::inout_ptr
|
[edit] Example
This section is incomplete Reason: no example |
[edit] See also
(C++23) |
interoperates with foreign pointer setters, obtains the initial pointer value from a smart pointer, and resets it on destruction (class template) |
(C++11) |
smart pointer with unique object ownership semantics (class template) |
(C++11) |
smart pointer with shared object ownership semantics (class template) |