|
|
|
22
Diagnostics library
[diagnostics]
22.1
General
[diagnostics.general]
1
This Clause describes components that C++ programs may use to detect and report error conditions.
2
The following subclauses describe components for reporting several kinds of exceptional conditions, docu-
menting program assertions, and a global variable for error number codes, as summarized in Table 33.
Table 33 — Diagnostics library summary
Subclause
Header(s)
22.2
Exception classes
<stdexcept>
22.3
Assertions
<cassert>
22.4
Error numbers
<cerrno>
22.5
System error support
<system_error>
22.2
Exception classes
[std.exceptions]
1
The C++ standard library provides classes to be used to report certain errors (20.5.5.12) in C++ programs.
In the error model reflected in these classes, errors are divided into two broad categories: logic errors and
runtime errors.
2
The distinguishing characteristic of logic errors is that they are due to errors in the internal logic of the
program. In theory, they are preventable.
3
By contrast, runtime errors are due to events beyond the scope of the program. They cannot be easily
predicted in advance. The header <stdexcept> defines several types of predefined exceptions for reporting
errors in a C++ program. These exceptions are related by inheritance.
22.2.1
Header <stdexcept> synopsis
[stdexcept.syn]
namespace std {
class logic_error;
class domain_error;
class invalid_argument;
class length_error;
class out_of_range;
class runtime_error;
class range_error;
class overflow_error;
class underflow_error;
}
22.2.2
Class logic_error
[logic.error]
namespace std {
class logic_error : public exception {
public:
explicit logic_error(const string& what_arg);
explicit logic_error(const char* what_arg);
};
}
1
The class logic_error defines the type of objects thrown as exceptions to report errors presumably detectable
before the program executes, such as violations of logical preconditions or class invariants.
logic_error(const string& what_arg);
2
Effects: Constructs an object of class logic_error.
3
Postconditions: strcmp(what(), what_arg.c_str()) == 0.
§ 22.2.2
472
logic_error(const char* what_arg);
4
Effects: Constructs an object of class logic_error.
5
Postconditions: strcmp(what(), what_arg) == 0.
22.2.3
Class domain_error
[domain.error]
namespace std {
class domain_error : public logic_error {
public:
explicit domain_error(const string& what_arg);
explicit domain_error(const char* what_arg);
};
}
1
The class domain_error defines the type of objects thrown as exceptions by the implementation to report
domain errors.
domain_error(const string& what_arg);
2
Effects: Constructs an object of class domain_error.
3
Postconditions: strcmp(what(), what_arg.c_str()) == 0.
domain_error(const char* what_arg);
4
Effects: Constructs an object of class domain_error.
5
Postconditions: strcmp(what(), what_arg) == 0.
22.2.4
Class invalid_argument
[invalid.argument]
namespace std {
class invalid_argument : public logic_error {
public:
explicit invalid_argument(const string& what_arg);
explicit invalid_argument(const char* what_arg);
};
}
1
The class invalid_argument defines the type of objects thrown as exceptions to report an invalid argument.
invalid_argument(const string& what_arg);
2
Effects: Constructs an object of class invalid_argument.
3
Postconditions: strcmp(what(), what_arg.c_str()) == 0.
invalid_argument(const char* what_arg);
4
Effects: Constructs an object of class invalid_argument.
5
Postconditions: strcmp(what(), what_arg) == 0.
22.2.5
Class length_error
[length.error]
namespace std {
class length_error : public logic_error {
public:
explicit length_error(const string& what_arg);
explicit length_error(const char* what_arg);
};
}
1
The class length_error defines the type of objects thrown as exceptions to report an attempt to produce an
object whose length exceeds its maximum allowable size.
length_error(const string& what_arg);
2
Effects: Constructs an object of class length_error.
3
Postconditions: strcmp(what(), what_arg.c_str()) == 0.
§ 22.2.5
473
length_error(const char* what_arg);
4
Effects: Constructs an object of class length_error.
5
Postconditions: strcmp(what(), what_arg) == 0.
22.2.6
Class out_of_range
[out.of.range]
namespace std {
class out_of_range : public logic_error {
public:
explicit out_of_range(const string& what_arg);
explicit out_of_range(const char* what_arg);
};
}
1
The class out_of_range defines the type of objects thrown as exceptions to report an argument value not in
its expected range.
out_of_range(const string& what_arg);
2
Effects: Constructs an object of class out_of_range.
3
Postconditions: strcmp(what(), what_arg.c_str()) == 0.
out_of_range(const char* what_arg);
4
Effects: Constructs an object of class out_of_range.
5
Postconditions: strcmp(what(), what_arg) == 0.
22.2.7
Class runtime_error
[runtime.error]
namespace std {
class runtime_error : public exception {
public:
explicit runtime_error(const string& what_arg);
explicit runtime_error(const char* what_arg);
};
}
1
The class runtime_error defines the type of objects thrown as exceptions to report errors presumably
detectable only when the program executes.
runtime_error(const string& what_arg);
2
Effects: Constructs an object of class runtime_error.
3
Postconditions: strcmp(what(), what_arg.c_str()) == 0.
runtime_error(const char* what_arg);
4
Effects: Constructs an object of class runtime_error.
5
Postconditions: strcmp(what(), what_arg) == 0.
22.2.8
Class range_error
[range.error]
namespace std {
class range_error : public runtime_error {
public:
explicit range_error(const string& what_arg);
explicit range_error(const char* what_arg);
};
}
1
The class range_error defines the type of objects thrown as exceptions to report range errors in internal
computations.
range_error(const string& what_arg);
2
Effects: Constructs an object of class range_error.
3
Postconditions: strcmp(what(), what_arg.c_str()) == 0.
§ 22.2.8
474
range_error(const char* what_arg);
4
Effects: Constructs an object of class range_error.
5
Postconditions: strcmp(what(), what_arg) == 0.
22.2.9
Class overflow_error
[overflow.error]
namespace std {
class overflow_error : public runtime_error {
public:
explicit overflow_error(const string& what_arg);
explicit overflow_error(const char* what_arg);
};
}
1
The class overflow_error defines the type of objects thrown as exceptions to report an arithmetic overflow
error.
overflow_error(const string& what_arg);
2
Effects: Constructs an object of class overflow_error.
3
Postconditions: strcmp(what(), what_arg.c_str()) ==
0.
overflow_error(const char* what_arg);
4
Effects: Constructs an object of class overflow_error.
5
Postconditions: strcmp(what(), what_arg) == 0.
22.2.10
Class underflow_error
[underflow.error]
namespace std {
class underflow_error : public runtime_error {
public:
explicit underflow_error(const string& what_arg);
explicit underflow_error(const char* what_arg);
};
}
1
The class underflow_error defines the type of objects thrown as exceptions to report an arithmetic underflow
error.
underflow_error(const string& what_arg);
2
Effects: Constructs an object of class underflow_error.
3
Postconditions: strcmp(what(), what_arg.c_str()) == 0.
underflow_error(const char* what_arg);
4
Effects: Constructs an object of class underflow_error.
5
Postconditions: strcmp(what(), what_arg) == 0.
22.3
Assertions
[assertions]
1
The header <cassert> provides a macro for documenting C++ program assertions and a mechanism for
disabling the assertion checks.
22.3.1
Header <cassert> synopsis
[cassert.syn]
#define assert(E) see below
1
The contents are the same as the C standard library header <assert.h>, except that a macro named
static_assert is not defined.
See also: ISO C 7.2
22.3.2
The assert macro
[assertions.assert]
1
An expression assert(E) is a constant subexpression (20.3.6), if
(1.1)
—
NDEBUG is defined at the point where assert is last defined or redefined, or
§ 22.3.2
475
(1.2)
—
E contextually converted to bool (Clause 7) is a constant subexpression that evaluates to the value
true.
22.4
Error numbers
[errno]
1
The contents of the header <cerrno> are the same as the POSIX header <errno.h>, except that errno shall
be defined as a macro. [Note: The intent is to remain in close alignment with the POSIX standard.
— end
note ] A separate errno value shall be provided for each thread.
22.4.1
Header <cerrno> synopsis
[cerrno.syn]
#define
errno see below
#define
E2BIG see below
#define
EACCES see below
#define
EADDRINUSE see below
#define
EADDRNOTAVAIL see below
#define
EAFNOSUPPORT see below
#define
EAGAIN see below
#define
EALREADY see below
#define
EBADF see below
#define
EBADMSG see below
#define
EBUSY see below
#define
ECANCELED see below
#define
ECHILD see below
#define
ECONNABORTED see below
#define
ECONNREFUSED see below
#define
ECONNRESET see below
#define
EDEADLK see below
#define
EDESTADDRREQ see below
#define
EDOM see below
#define
EEXIST see below
#define
EFAULT see below
#define
EFBIG see below
#define
EHOSTUNREACH see below
#define
EIDRM see below
#define
EILSEQ see below
#define
EINPROGRESS see below
#define
EINTR see below
#define
EINVAL see below
#define
EIO see below
#define
EISCONN see below
#define
EISDIR see below
#define
ELOOP see below
#define
EMFILE see below
#define
EMLINK see below
#define
EMSGSIZE see below
#define
ENAMETOOLONG see below
#define
ENETDOWN see below
#define
ENETRESET see below
#define
ENETUNREACH see below
#define
ENFILE see below
#define
ENOBUFS see below
#define
ENODATA see below
#define
ENODEV see below
#define
ENOENT see below
#define
ENOEXEC see below
#define
ENOLCK see below
#define
ENOLINK see below
#define
ENOMEM see below
#define
ENOMSG see below
#define
ENOPROTOOPT see below
#define
ENOSPC see below
#define
ENOSR see below
#define
ENOSTR see below
§
22.4.1
476
#define ENOSYS see below
#define ENOTCONN see below
#define ENOTDIR see below
#define ENOTEMPTY see below
#define ENOTRECOVERABLE see below
#define ENOTSOCK see below
#define ENOTSUP see below
#define ENOTTY see below
#define ENXIO see below
#define EOPNOTSUPP see below
#define EOVERFLOW see below
#define EOWNERDEAD see below
#define EPERM see below
#define EPIPE see below
#define EPROTO see below
#define EPROTONOSUPPORT see below
#define EPROTOTYPE see below
#define ERANGE see below
#define EROFS see below
#define ESPIPE see below
#define ESRCH see below
#define ETIME see below
#define ETIMEDOUT see below
#define ETXTBSY see below
#define EWOULDBLOCK see below
#define EXDEV see below
1
The meaning of the macros in this header is defined by the POSIX standard.
See also: ISO C 7.5
22.5
System error support
[syserr]
1
This subclause describes components that the standard library and C++ programs may use to report error
conditions originating from the operating system or other low-level application program interfaces.
2
Components described in this subclause shall not change the value of errno (22.4). Implementations should
leave the error states provided by other libraries unchanged.
22.5.1
Header <system_error> synopsis
[system_error.syn]
namespace std {
class error_category;
const error_category& generic_category() noexcept;
const error_category& system_category() noexcept;
class error_code;
class error_condition;
class system_error;
template<class T>
struct is_error_code_enum : public false_type {};
template<class T>
struct is_error_condition_enum : public false_type {};
enum class errc {
address_family_not_supported,
// EAFNOSUPPORT
address_in_use,
// EADDRINUSE
address_not_available,
// EADDRNOTAVAIL
already_connected,
// EISCONN
argument_list_too_long,
// E2BIG
argument_out_of_domain,
// EDOM
bad_address,
// EFAULT
bad_file_descriptor,
// EBADF
bad_message,
// EBADMSG
§ 22.5.1
477
broken_pipe,
// EPIPE
connection_aborted,
// ECONNABORTED
connection_already_in_progress,
// EALREADY
connection_refused,
// ECONNREFUSED
connection_reset,
// ECONNRESET
cross_device_link,
// EXDEV
destination_address_required,
// EDESTADDRREQ
device_or_resource_busy,
// EBUSY
directory_not_empty,
// ENOTEMPTY
executable_format_error,
// ENOEXEC
file_exists,
// EEXIST
file_too_large,
// EFBIG
filename_too_long,
// ENAMETOOLONG
function_not_supported,
// ENOSYS
host_unreachable,
// EHOSTUNREACH
identifier_removed,
// EIDRM
illegal_byte_sequence,
// EILSEQ
inappropriate_io_control_operation, // ENOTTY
interrupted,
// EINTR
invalid_argument,
// EINVAL
invalid_seek,
// ESPIPE
io_error,
// EIO
is_a_directory,
// EISDIR
message_size,
// EMSGSIZE
network_down,
// ENETDOWN
network_reset,
// ENETRESET
network_unreachable,
// ENETUNREACH
no_buffer_space,
// ENOBUFS
no_child_process,
// ECHILD
no_link,
// ENOLINK
no_lock_available,
// ENOLCK
no_message_available,
// ENODATA
no_message,
// ENOMSG
no_protocol_option,
// ENOPROTOOPT
no_space_on_device,
// ENOSPC
no_stream_resources,
// ENOSR
no_such_device_or_address,
// ENXIO
no_such_device,
// ENODEV
no_such_file_or_directory,
// ENOENT
no_such_process,
// ESRCH
not_a_directory,
// ENOTDIR
not_a_socket,
// ENOTSOCK
not_a_stream,
// ENOSTR
not_connected,
// ENOTCONN
not_enough_memory,
// ENOMEM
not_supported,
// ENOTSUP
operation_canceled,
// ECANCELED
operation_in_progress,
// EINPROGRESS
operation_not_permitted,
// EPERM
operation_not_supported,
// EOPNOTSUPP
operation_would_block,
// EWOULDBLOCK
owner_dead,
// EOWNERDEAD
permission_denied,
// EACCES
protocol_error,
// EPROTO
protocol_not_supported,
// EPROTONOSUPPORT
read_only_file_system,
// EROFS
resource_deadlock_would_occur,
// EDEADLK
resource_unavailable_try_again,
// EAGAIN
result_out_of_range,
// ERANGE
state_not_recoverable,
// ENOTRECOVERABLE
stream_timeout,
// ETIME
text_file_busy,
// ETXTBSY
timed_out,
// ETIMEDOUT
too_many_files_open_in_system,
// ENFILE
§
22.5.1
478
too_many_files_open,
// EMFILE
too_many_links,
// EMLINK
too_many_symbolic_link_levels,
// ELOOP
value_too_large,
// EOVERFLOW
wrong_protocol_type,
// EPROTOTYPE
};
template<> struct is_error_condition_enum<errc> : true_type {};
// 22.5.3.5, non-member functions
error_code make_error_code(errc e) noexcept;
template<class charT, class traits>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const error_code& ec);
// 22.5.4.5, non-member functions
error_condition make_error_condition(errc e) noexcept;
// 22.5.5, comparison functions
bool operator<(const error_code& lhs, const error_code& rhs) noexcept;
bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept;
bool operator==(const error_code& lhs, const error_code& rhs) noexcept;
bool operator==(const error_code& lhs, const error_condition& rhs) noexcept;
bool operator==(const error_condition& lhs, const error_code& rhs) noexcept;
bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept;
bool operator!=(const error_code& lhs, const error_code& rhs) noexcept;
bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept;
bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept;
bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept;
// 22.5.6, hash support
template<class T> struct hash;
template<> struct hash<error_code>;
template<> struct hash<error_condition>;
// 22.5, system error support
template<class T>
inline constexpr bool is_error_code_enum_v = is_error_code_enum<T>::value;
template<class T>
inline constexpr bool is_error_condition_enum_v = is_error_condition_enum<T>::value;
}
1
The value of each enum errc constant shall be the same as the value of the <cerrno> macro shown in
the above synopsis. Whether or not the <system_error> implementation exposes the <cerrno> macros is
unspecified.
2
The is_error_code_enum and is_error_condition_enum may be specialized for user-defined types to indi-
cate that such types are eligible for class error_code and class error_condition automatic conversions,
respectively.
22.5.2
Class error_category
[syserr.errcat]
22.5.2.1
Class error_category overview
[syserr.errcat.overview]
1
The class error_category serves as a base class for types used to identify the source and encoding of a
particular category of error code. Classes may be derived from error_category to support categories of errors
in addition to those defined in this document. Such classes shall behave as specified in this subclause 22.5.2.
[ Note: error_category objects are passed by reference, and two such objects are equal if they have the same
address. This means that applications using custom error_category types should create a single object of
each such type.
— end note ]
namespace std {
class error_category {
public:
constexpr error_category() noexcept;
§ 22.5.2.1
479
virtual ~error_category();
error_category(const error_category&) = delete;
error_category& operator=(const error_category&) = delete;
virtual const char* name() const noexcept = 0;
virtual error_condition default_error_condition(int ev) const noexcept;
virtual bool equivalent(int code, const error_condition& condition) const noexcept;
virtual bool equivalent(const error_code& code, int condition) const noexcept;
virtual string message(int ev) const = 0;
bool operator==(const error_category& rhs) const noexcept;
bool operator!=(const error_category& rhs) const noexcept;
bool operator<(const error_category& rhs) const noexcept;
};
const error_category& generic_category() noexcept;
const error_category& system_category() noexcept;
}
22.5.2.2
Class error_category virtual members
[syserr.errcat.virtuals]
virtual ~error_category();
1
Effects: Destroys an object of class error_category.
virtual const char* name() const noexcept = 0;
2
Returns: A string naming the error category.
virtual error_condition default_error_condition(int ev) const noexcept;
3
Returns: error_condition(ev, *this).
virtual bool equivalent(int code, const error_condition& condition) const noexcept;
4
Returns: default_error_condition(code) == condition.
virtual bool equivalent(const error_code& code, int condition) const noexcept;
5
Returns: *this == code.category() && code.value() == condition.
virtual string message(int ev) const = 0;
6
Returns: A string that describes the error condition denoted by ev.
22.5.2.3
Class error_category non-virtual members
[syserr.errcat.nonvirtuals]
constexpr error_category() noexcept;
1
Effects: Constructs an object of class error_category.
bool operator==(const error_category& rhs) const noexcept;
2
Returns: this == &rhs.
bool operator!=(const error_category& rhs) const noexcept;
3
Returns: !(*this == rhs).
bool operator<(const error_category& rhs) const noexcept;
4
Returns: less<const error_category*>()(this, &rhs).
[ Note: less (23.14.7) provides a total ordering for pointers.
— end note ]
22.5.2.4
Program defined classes derived from error_category
[syserr.errcat.derived]
virtual const char* name() const noexcept = 0;
1
Returns: A string naming the error category.
virtual error_condition default_error_condition(int ev) const noexcept;
2
Returns: An object of type error_condition that corresponds to ev.
§ 22.5.2.4
480
virtual bool equivalent(int code, const error_condition& condition) const noexcept;
3
Returns: true if, for the category of error represented by *this, code is considered equivalent to
condition; otherwise, false.
virtual bool equivalent(const error_code& code, int condition) const noexcept;
4
Returns: true if, for the category of error represented by *this, code is considered equivalent to
condition; otherwise, false.
22.5.2.5
Error category objects
[syserr.errcat.objects]
const error_category& generic_category() noexcept;
1
Returns: A reference to an object of a type derived from class error_category. All calls to this
function shall return references to the same object.
2
Remarks: The object’s default_error_condition and equivalent virtual functions shall behave as
specified for the class error_category. The object’s name virtual function shall return a pointer to
the string "generic".
const error_category& system_category() noexcept;
3
Returns: A reference to an object of a type derived from class error_category. All calls to this
function shall return references to the same object.
4
Remarks: The object’s equivalent virtual functions shall behave as specified for class error_category.
The object’s name virtual function shall return a pointer to the string "system". The object’s default_-
error_condition virtual function shall behave as follows:
If the argument ev corresponds to a POSIX errno value posv, the function shall return error_-
condition(posv, generic_category()). Otherwise, the function shall return error_condition(ev,
system_category()). What constitutes correspondence for any given operating system is unspecified.
[Note: The number of potential system error codes is large and unbounded, and some may not
correspond to any POSIX errno value. Thus implementations are given latitude in determining
correspondence.
— end note ]
22.5.3
Class error_code
[syserr.errcode]
22.5.3.1
Class error_code overview
[syserr.errcode.overview]
1
The class error_code describes an object used to hold error code values, such as those originating from the
operating system or other low-level application program interfaces. [ Note: Class error_code is an adjunct
to error reporting by exception.
— end note ]
namespace std {
class error_code {
public:
// 22.5.3.2, constructors
error_code() noexcept;
error_code(int val, const error_category& cat) noexcept;
template<class ErrorCodeEnum>
error_code(ErrorCodeEnum e) noexcept;
// 22.5.3.3, modifiers
void assign(int val, const error_category& cat) noexcept;
template<class ErrorCodeEnum>
error_code& operator=(ErrorCodeEnum e) noexcept;
void clear() noexcept;
// 22.5.3.4, observers
int value() const noexcept;
const error_category& category() const noexcept;
error_condition default_error_condition() const noexcept;
string message() const;
explicit operator bool() const noexcept;
§ 22.5.3.1
481
private:
int val_;
// exposition only
const error_category* cat_; // exposition only
};
// 22.5.3.5, non-member functions
error_code make_error_code(errc e) noexcept;
template<class charT, class traits>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os, const error_code& ec);
}
22.5.3.2
Class error_code constructors
[syserr.errcode.constructors]
error_code() noexcept;
1
Effects: Constructs an object of type error_code.
2
Postconditions: val_ == 0 and cat_ == &system_category().
error_code(int val, const error_category& cat) noexcept;
3
Effects: Constructs an object of type error_code.
4
Postconditions: val_ == val and cat_ == &cat.
template<class ErrorCodeEnum>
error_code(ErrorCodeEnum e) noexcept;
5
Effects: Constructs an object of type error_code.
6
Postconditions: *this == make_error_code(e).
7
Remarks: This constructor shall not participate in overload resolution unless
is_error_code_enum_v<ErrorCodeEnum> is true.
22.5.3.3
Class error_code modifiers
[syserr.errcode.modifiers]
void assign(int val, const error_category& cat) noexcept;
1
Postconditions: val_ == val and cat_ == &cat.
template<class ErrorCodeEnum>
error_code& operator=(ErrorCodeEnum e) noexcept;
2
Postconditions: *this == make_error_code(e).
3
Returns: *this.
4
Remarks: This operator shall not participate in overload resolution unless
is_error_code_enum_v<ErrorCodeEnum> is true.
void clear() noexcept;
5
Postconditions: value() == 0 and category() == system_category().
22.5.3.4
Class error_code observers
[syserr.errcode.observers]
int value() const noexcept;
1
Returns: val_.
const error_category& category() const noexcept;
2
Returns: *cat_.
error_condition default_error_condition() const noexcept;
3
Returns: category().default_error_condition(value()).
string message() const;
4
Returns: category().message(value()).
§ 22.5.3.4
482
explicit operator bool() const noexcept;
5
Returns: value() != 0.
22.5.3.5
Class error_code non-member functions
[syserr.errcode.nonmembers]
error_code make_error_code(errc e) noexcept;
1
Returns: error_code(static_cast<int>(e), generic_category()).
template<class charT, class traits>
basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const error_code& ec);
2
Effects: As if by: os << ec.category().name() << ’:’
<< ec.value();
22.5.4
Class error_condition
[syserr.errcondition]
22.5.4.1
Class error_condition overview
[syserr.errcondition.overview]
1
The class error_condition describes an object used to hold values identifying error conditions.
[Note:
error_condition values are portable abstractions, while error_code values (22.5.3) are implementation
specific.
— end note ]
namespace std {
class error_condition {
public:
// 22.5.4.2, constructors
error_condition() noexcept;
error_condition(int val, const error_category& cat) noexcept;
template<class ErrorConditionEnum>
error_condition(ErrorConditionEnum e) noexcept;
// 22.5.4.3, modifiers
void assign(int val, const error_category& cat) noexcept;
template<class ErrorConditionEnum>
error_condition& operator=(ErrorConditionEnum e) noexcept;
void clear() noexcept;
// 22.5.4.4, observers
int value() const noexcept;
const error_category& category() const noexcept;
string message() const;
explicit operator bool() const noexcept;
private:
int val_;
// exposition only
const error_category* cat_; // exposition only
};
}
22.5.4.2
Class error_condition constructors
[syserr.errcondition.constructors]
error_condition() noexcept;
1
Effects: Constructs an object of type error_condition.
2
Postconditions: val_ == 0 and cat_ == &generic_category().
error_condition(int val, const error_category& cat) noexcept;
3
Effects: Constructs an object of type error_condition.
4
Postconditions: val_ == val and cat_ == &cat.
template<class ErrorConditionEnum>
error_condition(ErrorConditionEnum e) noexcept;
5
Effects: Constructs an object of type error_condition.
6
Postconditions: *this == make_error_condition(e).
§ 22.5.4.2
483
7
Remarks: This constructor shall not participate in overload resolution unless
is_error_condition_enum_v<ErrorConditionEnum> is true.
22.5.4.3
Class error_condition modifiers
[syserr.errcondition.modifiers]
void assign(int val, const error_category& cat) noexcept;
1
Postconditions: val_ == val and cat_ == &cat.
template<class ErrorConditionEnum>
error_condition& operator=(ErrorConditionEnum e) noexcept;
2
Postconditions: *this == make_error_condition(e).
3
Returns: *this.
4
Remarks: This operator shall not participate in overload resolution unless
is_error_condition_enum_v<ErrorConditionEnum> is true.
void clear() noexcept;
5
Postconditions: value() == 0 and category() == generic_category().
22.5.4.4
Class error_condition observers
[syserr.errcondition.observers]
int value() const noexcept;
1
Returns: val_.
const error_category& category() const noexcept;
2
Returns: *cat_.
string message() const;
3
Returns: category().message(value()).
explicit operator bool() const noexcept;
4
Returns: value() != 0.
22.5.4.5
Class error_condition non-member functions
[syserr.errcondition.nonmembers]
error_condition make_error_condition(errc e) noexcept;
1
Returns: error_condition(static_cast<int>(e), generic_category()).
22.5.5
Comparison functions
[syserr.compare]
bool operator<(const error_code& lhs, const error_code& rhs) noexcept;
1
Returns:
lhs.category() < rhs.category() ||
(lhs.category() == rhs.category() && lhs.value() < rhs.value())
bool operator<(const error_condition& lhs, const error_condition& rhs) noexcept;
2
Returns:
lhs.category() < rhs.category() ||
(lhs.category() == rhs.category() && lhs.value() < rhs.value())
bool operator==(const error_code& lhs, const error_code& rhs) noexcept;
3
Returns:
lhs.category() == rhs.category() && lhs.value() == rhs.value()
bool operator==(const error_code& lhs, const error_condition& rhs) noexcept;
4
Returns:
lhs.category().equivalent(lhs.value(), rhs) || rhs.category().equivalent(lhs, rhs.value())
§ 22.5.5
484
bool operator==(const error_condition& lhs, const error_code& rhs) noexcept;
5
Returns:
rhs.category().equivalent(rhs.value(), lhs) || lhs.category().equivalent(rhs, lhs.value())
bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept;
6
Returns:
lhs.category() == rhs.category() && lhs.value() == rhs.value()
bool operator!=(const error_code& lhs, const error_code& rhs) noexcept;
bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept;
bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept;
bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept;
7
Returns: !(lhs == rhs).
22.5.6
System error hash support
[syserr.hash]
template<> struct hash<error_code>;
template<> struct hash<error_condition>;
1
The specializations are enabled (23.14.15).
22.5.7
Class system_error
[syserr.syserr]
22.5.7.1
Class system_error overview
[syserr.syserr.overview]
1
The class system_error describes an exception object used to report error conditions that have an associated
error code. Such error conditions typically originate from the operating system or other low-level application
program interfaces.
2
[Note: If an error represents an out-of-memory condition, implementations are encouraged to throw an
exception object of type bad_alloc (21.6.3.1) rather than system_error.
— end note ]
namespace std {
class system_error : public runtime_error {
public:
system_error(error_code ec, const string& what_arg);
system_error(error_code ec, const char* what_arg);
system_error(error_code ec);
system_error(int ev, const error_category& ecat, const string& what_arg);
system_error(int ev, const error_category& ecat, const char* what_arg);
system_error(int ev, const error_category& ecat);
const error_code& code() const noexcept;
const char* what() const noexcept override;
};
}
22.5.7.2
Class system_error members
[syserr.syserr.members]
system_error(error_code ec, const string& what_arg);
1
Effects: Constructs an object of class system_error.
2
Postconditions: code() == ec and string(what()).find(what_arg) != string::npos.
system_error(error_code ec, const char* what_arg);
3
Effects: Constructs an object of class system_error.
4
Postconditions: code() == ec and string(what()).find(what_arg) != string::npos.
system_error(error_code ec);
5
Effects: Constructs an object of class system_error.
6
Postconditions: code() == ec.
§ 22.5.7.2
485
system_error(int ev, const error_category& ecat, const string& what_arg);
7
Effects: Constructs an object of class system_error.
8
Postconditions: code() == error_code(ev, ecat) and
string(what()).find(what_arg) != string::npos.
system_error(int ev, const error_category& ecat, const char* what_arg);
9
Effects: Constructs an object of class system_error.
10
Postconditions: code() == error_code(ev, ecat) and
string(what()).find(what_arg) != string::npos.
system_error(int ev, const error_category& ecat);
11
Effects: Constructs an object of class system_error.
12
Postconditions: code() == error_code(ev, ecat).
const error_code& code() const noexcept;
13
Returns: ec or error_code(ev, ecat), from the constructor, as appropriate.
const char* what() const noexcept override;
14
Returns: An ntbs incorporating the arguments supplied in the constructor.
[Note: The returned ntbs might be the contents of what_arg + ": " + code.message(). — end
note ]
§ 22.5.7.2
486
23
General utilities library
[utilities]
23.1
General
[utilities.general]
1
This Clause describes utilities that are generally useful in C++ programs; some of these utilities are used by
other elements of the C++ standard library. These utilities are summarized in Table 34.
Table 34 — General utilities library summary
Subclause
Header(s)
23.2
Utility components
<utility>
23.3
Compile-time integer sequences
<utility>
23.4
Pairs
<utility>
23.5
Tuples
<tuple>
23.6
Optional objects
<optional>
23.7
Variants
<variant>
23.8
Storage for any type
<any>
23.9
Fixed-size sequences of bits
<bitset>
23.10
Memory
<memory>
<cstdlib>
23.11
Smart pointers
<memory>
23.12
Memory resources
<memory_resource>
23.13
Scoped allocators
<scoped_allocator>
23.14
Function objects
<functional>
23.15
Type traits
<type_traits>
23.16
Compile-time rational arithmetic
<ratio>
23.17
Time utilities
<chrono>
<ctime>
23.18
Type indexes
<typeindex>
23.19
Execution policies
<execution>
23.20
Primitive numeric conversions
<charconv>
23.2
Utility components
[utility]
1
This subclause contains some basic function and class templates that are used throughout the rest of the
library.
23.2.1
Header <utility> synopsis
[utility.syn]
#include <initializer_list>
// see 21.9.1
namespace std {
// 23.2.2, swap
template<class T>
void swap(T& a, T& b) noexcept(see below );
template<class T, size_t N>
void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v<T>);
// 23.2.3, exchange
template<class T, class U = T>
constexpr T exchange(T& obj, U&& new_val);
// 23.2.4, forward/move
template<class T>
constexpr T&& forward(remove_reference_t<T>& t) noexcept;
template<class T>
constexpr T&& forward(remove_reference_t<T>&& t) noexcept;
§ 23.2.1
487
template<class T>
constexpr remove_reference_t<T>&& move(T&&) noexcept;
template<class T>
constexpr conditional_t<
!is_nothrow_move_constructible_v<T> && is_copy_constructible_v<T>,
const
T&,
T&&>
move_if_noexcept(T& x) noexcept;
// 23.2.5, as_const
template<class T>
constexpr add_const_t<T>& as_const(T& t) noexcept;
template<class T>
void as_const(const T&&) = delete;
// 23.2.6, declval
template<class T>
add_rvalue_reference_t<T> declval() noexcept;
// as unevaluated operand
// 23.3, Compile-time integer sequences
template<class T, T...>
struct integer_sequence;
template<size_t... I>
using index_sequence = integer_sequence<size_t, I...>;
template<class T, T N>
using make_integer_sequence = integer_sequence<T, see below >;
template<size_t N>
using make_index_sequence = make_integer_sequence<size_t, N>;
template<class... T>
using index_sequence_for = make_index_sequence<sizeof...(T)>;
// 23.4, class template pair
template<class T1, class T2>
struct pair;
// 23.4.3, pair specialized algorithms
template<class T1, class T2>
constexpr bool operator==(const pair<T1, T2>&, const pair<T1,
T2>&);
template<class T1, class T2>
constexpr bool operator< (const pair<T1, T2>&, const pair<T1,
T2>&);
template<class T1, class T2>
constexpr bool operator!=(const pair<T1, T2>&, const pair<T1,
T2>&);
template<class T1, class T2>
constexpr bool operator> (const pair<T1, T2>&, const pair<T1,
T2>&);
template<class T1, class T2>
constexpr bool operator>=(const pair<T1, T2>&, const pair<T1,
T2>&);
template<class T1, class T2>
constexpr bool operator<=(const pair<T1, T2>&, const pair<T1,
T2>&);
template<class T1, class T2>
void swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));
template<class T1, class T2>
constexpr see below make_pair(T1&&, T2&&);
// 23.4.4, tuple-like access to pair
template<class T> class tuple_size;
template<size_t I, class T> class tuple_element;
template<class T1, class T2> struct tuple_size<pair<T1, T2>>;
template<size_t I, class T1, class T2> struct tuple_element<I, pair<T1, T2>>;
template<size_t I, class T1, class T2>
constexpr tuple_element_t<I, pair<T1, T2>>& get(pair<T1, T2>&) noexcept;
§
23.2.1
488
template<size_t I, class T1, class T2>
constexpr tuple_element_t<I, pair<T1, T2>>&& get(pair<T1, T2>&&) noexcept;
template<size_t I, class T1, class T2>
constexpr const tuple_element_t<I, pair<T1, T2>>& get(const pair<T1, T2>&) noexcept;
template<size_t I, class T1, class T2>
constexpr const tuple_element_t<I, pair<T1, T2>>&& get(const pair<T1,
T2>&&)
noexcept;
template<class T1, class T2>
constexpr T1& get(pair<T1, T2>& p) noexcept;
template<class T1, class T2>
constexpr const T1& get(const pair<T1, T2>& p) noexcept;
template<class T1, class T2>
constexpr T1&& get(pair<T1, T2>&& p) noexcept;
template<class T1, class T2>
constexpr const T1&& get(const pair<T1, T2>&& p) noexcept;
template<class T2, class T1>
constexpr T2& get(pair<T1, T2>& p) noexcept;
template<class T2, class T1>
constexpr const T2& get(const pair<T1, T2>& p) noexcept;
template<class T2, class T1>
constexpr T2&& get(pair<T1, T2>&& p) noexcept;
template<class T2, class T1>
constexpr const T2&& get(const pair<T1, T2>&& p) noexcept;
// 23.4.5, pair piecewise construction
struct piecewise_construct_t {
explicit piecewise_construct_t() = default;
};
inline constexpr piecewise_construct_t piecewise_construct{};
template<class... Types> class tuple;
// defined in <tuple> (23.5.2)
// in-place construction
struct in_place_t {
explicit in_place_t() = default;
};
inline constexpr in_place_t in_place{};
template<class T>
struct in_place_type_t {
explicit in_place_type_t() = default;
};
template<class T> inline constexpr in_place_type_t<T> in_place_type{};
template<size_t I>
struct in_place_index_t {
explicit in_place_index_t() = default;
};
template<size_t I> inline constexpr in_place_index_t<I> in_place_index{};
}
1
The header <utility> defines several types and function templates that are described in this Clause. It also
defines the template pair and various function templates that operate on pair objects.
2
The type chars_format is a bitmask type (20.4.2.1.4) with elements scientific, fixed, and hex.
23.2.2
swap
[utility.swap]
template<class T>
void swap(T& a, T& b) noexcept(see below );
1
Remarks: This function shall not participate in overload resolution unless is_move_constructible_-
v<T> is true and is_move_assignable_v<T> is true. The expression inside noexcept is equivalent
to:
is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<T>
2
Requires: Type T shall be MoveConstructible (Table 23) and MoveAssignable (Table 25).
3
Effects: Exchanges values stored in two locations.
§ 23.2.2
489
template<class T, size_t N>
void swap(T (&a)[N], T (&b)[N]) noexcept(is_nothrow_swappable_v<T>);
4
Remarks: This function shall not participate in overload resolution unless is_swappable_v<T> is true.
5
Requires: a[i] shall be swappable with (20.5.3.2) b[i] for all i in the range [0, N).
6
Effects: As if by swap_ranges(a, a + N, b).
23.2.3
exchange
[utility.exchange]
template<class T, class U = T>
constexpr T exchange(T& obj, U&& new_val);
1
Effects: Equivalent to:
T old_val = std::move(obj);
obj = std::forward<U>(new_val);
return old_val;
23.2.4
Forward/move helpers
[forward]
1
The library provides templated helper functions to simplify applying move semantics to an lvalue and to
simplify the implementation of forwarding functions. All functions specified in this subclause are signal-
safe (21.11.4).
template<class T> constexpr T&& forward(remove_reference_t<T>& t) noexcept;
template<class T> constexpr T&& forward(remove_reference_t<T>&& t) noexcept;
2
Returns: static_cast<T&&>(t).
3
Remarks: If the second form is instantiated with an lvalue reference type, the program is ill-formed.
4
[ Example:
template<class T, class A1, class A2>
shared_ptr<T> factory(A1&& a1, A2&& a2) {
return shared_ptr<T>(new T(std::forward<A1>(a1), std::forward<A2>(a2)));
}
struct A {
A(int&, const double&);
};
void g() {
shared_ptr<A> sp1 = factory<A>(2, 1.414); // error: 2 will not bind to int&
int i = 2;
shared_ptr<A> sp2 = factory<A>(i, 1.414); // OK
}
In the first call to factory, A1 is deduced as int, so 2 is forwarded to A’s constructor as an rvalue. In
the second call to factory, A1 is deduced as int&, so i is forwarded to A’s constructor as an lvalue.
In both cases, A2 is deduced as double, so 1.414 is forwarded to A’s constructor as an rvalue.
— end
example ]
template<class T> constexpr remove_reference_t<T>&& move(T&& t) noexcept;
5
Returns: static_cast<remove_reference_t<T>&&>(t).
6
[ Example:
template<class T, class A1>
shared_ptr<T> factory(A1&& a1) {
return shared_ptr<T>(new T(std::forward<A1>(a1)));
}
struct A {
A();
A(const A&);
// copies from lvalues
A(A&&);
// moves from rvalues
};
§ 23.2.4
490
void g() {
A a;
shared_ptr<A> sp1 = factory<A>(a);
// “a” binds to A(const A&)
shared_ptr<A> sp1 = factory<A>(std::move(a));
// “a” binds to A(A&&)
}
In the first call to factory, A1 is deduced as A&, so a is forwarded as a non-const lvalue. This binds to
the constructor A(const A&), which copies the value from a. In the second call to factory, because of
the call std::move(a), A1 is deduced as A, so a is forwarded as an rvalue. This binds to the constructor
A(A&&), which moves the value from a. — end example ]
template<class T> constexpr conditional_t<
!is_nothrow_move_constructible_v<T> && is_copy_constructible_v<T>, const T&, T&&>
move_if_noexcept(T& x) noexcept;
7
Returns: std::move(x).
23.2.5
Function template as_const
[utility.as_const]
template<class T> constexpr add_const_t<T>& as_const(T& t) noexcept;
1
Returns: t.
23.2.6
Function template declval
[declval]
1
The library provides the function template declval to simplify the definition of expressions which occur as
unevaluated operands (8.2).
template<class T> add_rvalue_reference_t<T> declval() noexcept;
// as unevaluated operand
2
Remarks: If this function is odr-used (6.2), the program is ill-formed.
3
Remarks: The template parameter T of declval may be an incomplete type.
4
[ Example:
template<class To, class From> decltype(static_cast<To>(declval<From>())) convert(From&&);
declares a function template convert which only participates in overloading if the type From can be explicitly
converted to type To. For another example see class template common_type (23.15.7.6).
— end example ]
23.3
Compile-time integer sequences
[intseq]
23.3.1
In general
[intseq.general]
1
The library provides a class template that can represent an integer sequence. When used as an argument to
a function template the parameter pack defining the sequence can be deduced and used in a pack expansion.
[ Note: The index_sequence alias template is provided for the common case of an integer sequence of type
size_t; see also 23.5.3.5.
— end note ]
23.3.2
Class template integer_sequence
[intseq.intseq]
namespace std {
template<class T, T... I>
struct integer_sequence {
using value_type = T;
static constexpr size_t size() noexcept { return sizeof...(I); }
};
}
1
T shall be an integer type.
23.3.3
Alias template make_integer_sequence
[intseq.make]
template<class T, T N>
using make_integer_sequence = integer_sequence<T, see below >;
1
If N is negative the program is ill-formed. The alias template make_integer_sequence denotes a
specialization of integer_sequence with N template non-type arguments. The type make_integer_-
sequence<T, N> denotes the type integer_sequence<T, 0, 1, ..., N-1>. [ Note: make_integer_-
sequence<int, 0> denotes the type integer_sequence<int> — end note ]
§ 23.3.3
491
23.4
Pairs
[pairs]
23.4.1
In general
[pairs.general]
1
The library provides a template for heterogeneous pairs of values. The library also provides a matching
function template to simplify their construction and several templates that provide access to pair objects as
if they were tuple objects (see 23.5.3.6 and 23.5.3.7).
23.4.2
Class template pair
[pairs.pair]
namespace std {
template<class T1, class T2>
struct pair {
using first_type
= T1;
using second_type = T2;
T1 first;
T2 second;
pair(const pair&) = default;
pair(pair&&) = default;
EXPLICIT constexpr pair();
EXPLICIT constexpr pair(const T1& x, const T2& y);
template<class U1, class U2> EXPLICIT constexpr pair(U1&& x, U2&& y);
template<class U1, class U2> EXPLICIT constexpr pair(const pair<U1, U2>& p);
template<class U1, class U2> EXPLICIT constexpr pair(pair<U1, U2>&& p);
template<class... Args1, class... Args2>
pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args);
pair& operator=(const pair& p);
template<class U1, class U2> pair& operator=(const pair<U1, U2>& p);
pair& operator=(pair&& p) noexcept(see below );
template<class U1, class U2> pair& operator=(pair<U1, U2>&& p);
void swap(pair& p) noexcept(see below );
};
template<class T1, class T2>
pair(T1, T2) -> pair<T1, T2>;
}
1
Constructors and member functions of pair shall not throw exceptions unless one of the element-wise
operations specified to be called for that operation throws an exception.
2
The defaulted move and copy constructor, respectively, of pair shall be a constexpr function if and only if
all required element-wise initializations for copy and move, respectively, would satisfy the requirements for a
constexpr function. The destructor of pair shall be a trivial destructor if (is_trivially_destructible_-
v<T1> && is_trivially_destructible_v<T2>) is true.
EXPLICIT constexpr pair();
3
Effects: Value-initializes first and second.
4
Remarks: This constructor shall not participate in overload resolution unless is_default_construct-
ible_v<first_type> is true and is_default_constructible_v<second_type> is true. [ Note: This
behavior can be implemented by a constructor template with default template arguments.
— end
note ] The constructor is explicit if and only if either first_type or second_type is not implicitly
default-constructible. [ Note: This behavior can be implemented with a trait that checks whether a
const first_type& or a const second_type& can be initialized with {}.
— end note ]
EXPLICIT constexpr pair(const T1& x, const T2& y);
5
Effects: Initializes first with x and second with y.
6
Remarks: This constructor shall not participate in overload resolution unless is_copy_construct-
ible_v<first_type> is true and is_copy_constructible_v<second_type> is true. The constructor
is explicit if and only if is_convertible_v<const first_type&, first_type> is false or is_-
convertible_v<const second_type&, second_type> is false.
§ 23.4.2
492
template<class U1, class U2> EXPLICIT constexpr pair(U1&& x, U2&& y);
7
Effects: Initializes first with std::forward<U1>(x) and second with std::forward<U2>(y).
8
Remarks: This constructor shall not participate in overload resolution unless is_constructible_-
v<first_type, U1&&> is true and is_constructible_v<second_type, U2&&> is true. The construc-
tor is explicit if and only if is_convertible_v<U1&&, first_type> is false or is_convertible_-
v<U2&&, second_type> is false.
template<class U1, class U2> EXPLICIT constexpr pair(const pair<U1, U2>& p);
9
Effects: Initializes members from the corresponding members of the argument.
10
Remarks: This constructor shall not participate in overload resolution unless is_constructible_-
v<first_type, const U1&> is true and is_constructible_v<second_type, const U2&> is true.
The constructor is explicit if and only if is_convertible_v<const U1&, first_type> is false or
is_convertible_v<const U2&, second_type> is false.
template<class U1, class U2> EXPLICIT constexpr pair(pair<U1, U2>&& p);
11
Effects: Initializes first with std::forward<U1>(p.first) and second with std::forward<U2>(
p.second).
12
Remarks: This constructor shall not participate in overload resolution unless is_constructible_-
v<first_type, U1&&> is true and is_constructible_v<second_type, U2&&> is true. The construc-
tor is explicit if and only if is_convertible_v<U1&&, first_type> is false or is_convertible_-
v<U2&&, second_type> is false.
template<class... Args1, class... Args2>
pair(piecewise_construct_t, tuple<Args1...> first_args, tuple<Args2...> second_args);
13
Requires: is_constructible_v<first_type, Args1&&...> is true and is_constructible_v<sec-
ond_type, Args2&&...> is true.
14
Effects: Initializes first with arguments of types Args1... obtained by forwarding the elements of
first_args and initializes second with arguments of types Args2... obtained by forwarding the
elements of second_args.
(Here, forwarding an element x of type U within a tuple object means
calling std::forward<U>(x).) This form of construction, whereby constructor arguments for first
and second are each provided in a separate tuple object, is called piecewise construction.
pair& operator=(const pair& p);
15
Effects: Assigns p.first to first and p.second to second.
16
Remarks: This operator shall be defined as deleted unless is_copy_assignable_v<first_type> is
true and is_copy_assignable_v<second_type> is true.
17
Returns: *this.
template<class U1, class U2> pair& operator=(const pair<U1, U2>& p);
18
Effects: Assigns p.first to first and p.second to second.
19
Remarks: This operator shall not participate in overload resolution unless is_assignable_v<first_-
type&, const U1&> is true and is_assignable_v<second_type&, const U2&> is true.
20
Returns: *this.
pair& operator=(pair&& p) noexcept(see below );
21
Effects: Assigns to first with std::forward<first_type>(p.first) and to second with
std::forward<second_type>(p.second).
22
Remarks: This operator shall not participate in overload resolution unless is_move_assignable_-
v<first_type> is true and is_move_assignable_v<second_type> is true.
23
Remarks: The expression inside noexcept is equivalent to:
is_nothrow_move_assignable_v<T1> && is_nothrow_move_assignable_v<T2>
24
Returns: *this.
§ 23.4.2
493
template<class U1, class U2> pair& operator=(pair<U1, U2>&& p);
25
Effects: Assigns to first with std::forward<U>(p.first) and to second with
std::forward<V>(p.second).
26
Remarks: This operator shall not participate in overload resolution unless is_assignable_v<first_-
type&, U1&&> is true and is_assignable_v<second_type&, U2&&> is true.
27
Returns: *this.
void swap(pair& p) noexcept(see below );
28
Requires: first shall be swappable with (20.5.3.2) p.first and second shall be swappable with
p.second.
29
Effects: Swaps first with p.first and second with p.second.
30
Remarks: The expression inside noexcept is equivalent to:
is_nothrow_swappable_v<first_type> && is_nothrow_swappable_v<second_type>
23.4.3
Specialized algorithms
[pairs.spec]
template<class T1, class T2>
constexpr bool operator==(const pair<T1, T2>& x, const pair<T1, T2>& y);
1
Returns: x.first == y.first && x.second == y.second.
template<class T1, class T2>
constexpr bool operator<(const pair<T1, T2>& x, const pair<T1, T2>& y);
2
Returns: x.first < y.first || (!(y.first < x.first) && x.second
<
y.second).
template<class T1, class T2>
constexpr bool operator!=(const pair<T1, T2>& x, const pair<T1, T2>& y);
3
Returns: !(x == y).
template<class T1, class T2>
constexpr bool operator>(const pair<T1, T2>& x, const pair<T1, T2>& y);
4
Returns: y < x.
template<class T1, class T2>
constexpr bool operator>=(const pair<T1, T2>& x, const pair<T1, T2>& y);
5
Returns: !(x < y).
template<class T1, class T2>
constexpr bool operator<=(const pair<T1, T2>& x, const pair<T1, T2>& y);
6
Returns: !(y < x).
template<class T1, class T2> void swap(pair<T1, T2>& x, pair<T1, T2>& y)
noexcept(noexcept(x.swap(y)));
7
Effects: As if by x.swap(y).
8
Remarks: This function shall not participate in overload resolution unless is_swappable_v<T1> is
true and is_swappable_v<T2> is true.
template<class T1, class T2>
constexpr pair<V1, V2> make_pair(T1&& x, T2&& y);
9
Returns: pair<V1, V2>(std::forward<T1>(x), std::forward<T2>(y)), where V1 and V2 are deter-
mined as follows: Let Ui be decay_t<Ti> for each Ti. If Ui is a specialization of reference_wrapper,
then Vi is Ui::type&, otherwise Vi is Ui.
10
[ Example: In place of:
return pair<int, double>(5, 3.1415926);
// explicit types
a C++ program may contain:
return make_pair(5, 3.1415926);
// types are deduced
§ 23.4.3
494
— end example ]
23.4.4
Tuple-like access to pair
[pair.astuple]
template<class T1, class T2>
struct tuple_size<pair<T1, T2>> : integral_constant<size_t, 2> { };
tuple_element<I, pair<T1, T2>>::type
1
Requires: I < 2. The program is ill-formed if I is out of bounds.
2
Value: The type T1 if I == 0, otherwise the type T2.
template<size_t I, class T1, class T2>
constexpr tuple_element_t<I, pair<T1, T2>>& get(pair<T1, T2>& p) noexcept;
template<size_t I, class T1, class T2>
constexpr const tuple_element_t<I, pair<T1, T2>>& get(const pair<T1, T2>& p) noexcept;
template<size_t I, class T1, class T2>
constexpr tuple_element_t<I, pair<T1, T2>>&& get(pair<T1, T2>&& p) noexcept;
template<size_t I, class T1, class T2>
constexpr const tuple_element_t<I, pair<T1, T2>>&& get(const pair<T1, T2>&& p) noexcept;
3
Returns: If I == 0 returns a reference to p.first; if I == 1 returns a reference to p.second; otherwise
the program is ill-formed.
template<class T1, class T2>
constexpr T1& get(pair<T1, T2>& p) noexcept;
template<class T1, class T2>
constexpr const T1& get(const pair<T1, T2>& p) noexcept;
template<class T1, class T2>
constexpr T1&& get(pair<T1, T2>&& p) noexcept;
template<class T1, class T2>
constexpr const T1&& get(const pair<T1, T2>&& p) noexcept;
4
Requires: T1 and T2 are distinct types. Otherwise, the program is ill-formed.
5
Returns: A reference to p.first.
template<class T2, class T1>
constexpr T2& get(pair<T1, T2>& p) noexcept;
template<class T2, class T1>
constexpr const T2& get(const pair<T1, T2>& p) noexcept;
template<class T2, class T1>
constexpr T2&& get(pair<T1, T2>&& p) noexcept;
template<class T2, class T1>
constexpr const T2&& get(const pair<T1, T2>&& p) noexcept;
6
Requires: T1 and T2 are distinct types. Otherwise, the program is ill-formed.
7
Returns: A reference to p.second.
23.4.5
Piecewise construction
[pair.piecewise]
struct piecewise_construct_t {
explicit piecewise_construct_t() = default;
};
inline constexpr piecewise_construct_t piecewise_construct{};
1
The struct piecewise_construct_t is an empty structure type used as a unique type to disambiguate
constructor and function overloading. Specifically, pair has a constructor with piecewise_construct_t as
the first argument, immediately followed by two tuple (23.5) arguments used for piecewise construction of
the elements of the pair object.
23.5
Tuples
[tuple]
23.5.1
In general
[tuple.general]
1
This subclause describes the tuple library that provides a tuple type as the class template tuple that can be
instantiated with any number of arguments. Each template argument specifies the type of an element in the
§ 23.5.1
495
tuple. Consequently, tuples are heterogeneous, fixed-size collections of values. An instantiation of tuple
with two arguments is similar to an instantiation of pair with the same two arguments. See
23.4.
23.5.2
Header <tuple> synopsis
[tuple.syn]
namespace std {
// 23.5.3, class template tuple
template<class... Types>
class tuple;
// 23.5.3.4, tuple creation functions
inline constexpr unspecified ignore;
template<class... TTypes>
constexpr tuple<VTypes...> make_tuple(TTypes&&...);
template<class... TTypes>
constexpr tuple<TTypes&&...> forward_as_tuple(TTypes&&...) noexcept;
template<class... TTypes>
constexpr tuple<TTypes&...> tie(TTypes&...) noexcept;
template<class... Tuples>
constexpr tuple<CTypes...> tuple_cat(Tuples&&...);
// 23.5.3.5, calling a function with a tuple of arguments
template<class F, class Tuple>
constexpr decltype(auto) apply(F&& f, Tuple&& t);
template<class T, class Tuple>
constexpr T make_from_tuple(Tuple&& t);
// 23.5.3.6, tuple helper classes
template<class T> class tuple_size;
// not defined
template<class T> class tuple_size<const T>;
template<class T> class tuple_size<volatile T>;
template<class T> class tuple_size<const volatile T>;
template<class... Types> class tuple_size<tuple<Types...>>;
template<size_t I, class T> class tuple_element;
// not defined
template<size_t I, class T> class tuple_element<I, const T>;
template<size_t I, class T> class tuple_element<I, volatile T>;
template<size_t I, class T> class tuple_element<I, const volatile
T>;
template<size_t I, class... Types>
class tuple_element<I, tuple<Types...>>;
template<size_t I, class T>
using tuple_element_t = typename tuple_element<I, T>::type;
// 23.5.3.7, element access
template<size_t I, class... Types>
constexpr tuple_element_t<I, tuple<Types...>>& get(tuple<Types...>&)
noexcept;
template<size_t I, class... Types>
constexpr tuple_element_t<I, tuple<Types...>>&& get(tuple<Types...>&&) noexcept;
template<size_t I, class... Types>
constexpr const tuple_element_t<I, tuple<Types...>>& get(const tuple<Types...>&)
noexcept;
template<size_t I, class... Types>
constexpr const tuple_element_t<I, tuple<Types...>>&& get(const tuple<Types...>&&) noexcept;
template<class T, class... Types>
constexpr T& get(tuple<Types...>& t) noexcept;
template<class T, class... Types>
constexpr T&& get(tuple<Types...>&& t) noexcept;
§
23.5.2
496
template<class T, class... Types>
constexpr const T& get(const tuple<Types...>& t) noexcept;
template<class T, class... Types>
constexpr const T&& get(const tuple<Types...>&& t) noexcept;
// 23.5.3.8, relational operators
template<class... TTypes, class... UTypes>
constexpr bool operator==(const tuple<TTypes...>&, const tuple<UTypes...>&);
template<class... TTypes, class... UTypes>
constexpr bool operator<(const tuple<TTypes...>&, const tuple<UTypes...>&);
template<class... TTypes, class... UTypes>
constexpr bool operator!=(const tuple<TTypes...>&, const tuple<UTypes...>&);
template<class... TTypes, class... UTypes>
constexpr bool operator>(const tuple<TTypes...>&, const tuple<UTypes...>&);
template<class... TTypes, class... UTypes>
constexpr bool operator<=(const tuple<TTypes...>&, const tuple<UTypes...>&);
template<class... TTypes, class... UTypes>
constexpr bool operator>=(const tuple<TTypes...>&, const tuple<UTypes...>&);
// 23.5.3.9, allocator-related traits
template<class... Types, class Alloc>
struct uses_allocator<tuple<Types...>, Alloc>;
// 23.5.3.10, specialized algorithms
template<class... Types>
void swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(see below );
// 23.5.3.6, tuple helper classes
template<class T>
inline constexpr size_t tuple_size_v = tuple_size<T>::value;
}
23.5.3
Class template tuple
[tuple.tuple]
namespace std {
template<class... Types>
class tuple {
public:
// 23.5.3.1, tuple construction
EXPLICIT constexpr tuple();
EXPLICIT constexpr tuple(const Types&...);
// only if
sizeof...(Types)
>=
1
template<class... UTypes>
EXPLICIT constexpr tuple(UTypes&&...);
// only if
sizeof...(Types)
>=
1
tuple(const tuple&) = default;
tuple(tuple&&) = default;
template<class... UTypes>
EXPLICIT constexpr tuple(const tuple<UTypes...>&);
template<class... UTypes>
EXPLICIT constexpr tuple(tuple<UTypes...>&&);
template<class U1, class U2>
EXPLICIT constexpr tuple(const pair<U1, U2>&);
// only if
sizeof...(Types)
==
2
template<class U1, class U2>
EXPLICIT constexpr tuple(pair<U1, U2>&&);
// only if
sizeof...(Types)
==
2
// allocator-extended constructors
template<class Alloc>
tuple(allocator_arg_t, const Alloc& a);
template<class Alloc>
EXPLICIT tuple(allocator_arg_t, const Alloc& a, const Types&...);
template<class Alloc, class... UTypes>
EXPLICIT tuple(allocator_arg_t, const Alloc& a, UTypes&&...);
§
23.5.3
497
template<class Alloc>
tuple(allocator_arg_t, const Alloc& a, const tuple&);
template<class Alloc>
tuple(allocator_arg_t, const Alloc& a, tuple&&);
template<class Alloc, class... UTypes>
EXPLICIT tuple(allocator_arg_t, const Alloc& a,
const tuple<UTypes...>&);
template<class Alloc, class... UTypes>
EXPLICIT tuple(allocator_arg_t, const Alloc& a,
tuple<UTypes...>&&);
template<class Alloc, class U1, class U2>
EXPLICIT tuple(allocator_arg_t, const Alloc& a,
const pair<U1, U2>&);
template<class Alloc, class U1, class U2>
EXPLICIT tuple(allocator_arg_t, const Alloc& a,
pair<U1, U2>&&);
// 23.5.3.2, tuple assignment
tuple& operator=(const tuple&);
tuple& operator=(tuple&&) noexcept(see below );
template<class... UTypes>
tuple& operator=(const tuple<UTypes...>&);
template<class... UTypes>
tuple& operator=(tuple<UTypes...>&&);
template<class U1, class U2>
tuple& operator=(const pair<U1, U2>&);
// only if sizeof...(Types)
==
2
template<class U1, class U2>
tuple& operator=(pair<U1, U2>&&);
// only if sizeof...(Types)
==
2
// 23.5.3.3, tuple swap
void swap(tuple&) noexcept(see below );
};
template<class... UTypes>
tuple(UTypes...) -> tuple<UTypes...>;
template<class T1, class T2>
tuple(pair<T1, T2>) -> tuple<T1, T2>;
template<class Alloc, class... UTypes>
tuple(allocator_arg_t, Alloc, UTypes...) -> tuple<UTypes...>;
template<class Alloc, class T1, class T2>
tuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>;
template<class Alloc, class... UTypes>
tuple(allocator_arg_t, Alloc, tuple<UTypes...>) -> tuple<UTypes...>;
}
23.5.3.1
Construction
[tuple.cnstr]
1
For each tuple constructor, an exception is thrown only if the construction of one of the types in Types
throws an exception.
2
The defaulted move and copy constructor, respectively, of tuple shall be a constexpr function if and only if
all required element-wise initializations for copy and move, respectively, would satisfy the requirements for a
constexpr function. The defaulted move and copy constructor of tuple<> shall be constexpr functions.
3
The destructor of tuple shall be a trivial destructor if (is_trivially_destructible_v<Types> && ...)
is true.
4
In the constructor descriptions that follow, let i be in the range [0, sizeof...(Types)) in order, Ti be the
ith type in Types, and Ui be the ith type in a template parameter pack named UTypes, where indexing is
zero-based.
EXPLICIT constexpr tuple();
5
Effects: Value-initializes each element.
6
Remarks: This constructor shall not participate in overload resolution unless is_default_construct-
ible_v<Ti> is true for all i. [ Note: This behavior can be implemented by a constructor template with
default template arguments.
— end note ] The constructor is explicit if and only if Ti is not implicitly
§ 23.5.3.1
498
default-constructible for at least one i. [Note: This behavior can be implemented with a trait that
checks whether a const Ti& can be initialized with {}.
— end note ]
EXPLICIT constexpr tuple(const Types&...);
7
Effects: Initializes each element with the value of the corresponding parameter.
8
Remarks: This constructor shall not participate in overload resolution unless sizeof...(Types) >=
1 and is_copy_constructible_v<Ti> is true for all i. The constructor is explicit if and only if
is_convertible_v<const Ti&, Ti> is false for at least one i.
template<class... UTypes> EXPLICIT constexpr tuple(UTypes&&... u);
9
Effects: Initializes the elements in the tuple with the corresponding value in std::forward<UTypes>(u).
10
Remarks: This constructor shall not participate in overload resolution unless sizeof...(Types) ==
sizeof...(UTypes) and sizeof...(Types) >= 1 and is_constructible_v<Ti, Ui&&> is true for
all i. The constructor is explicit if and only if is_convertible_v<Ui&&, Ti> is false for at least one i.
tuple(const tuple& u) = default;
11
Requires: is_copy_constructible_v<Ti> is true for all i.
12
Effects: Initializes each element of *this with the corresponding element of u.
tuple(tuple&& u) = default;
13
Requires: is_move_constructible_v<Ti> is true for all i.
14
Effects: For all i, initializes the ith element of *this with std::forward<Ti>(get<i>(u)).
template<class... UTypes> EXPLICIT constexpr tuple(const tuple<UTypes...>& u);
15
Effects: Initializes each element of *this with the corresponding element of u.
16
Remarks: This constructor shall not participate in overload resolution unless
(16.1)
—
sizeof...(Types) == sizeof...(UTypes) and
(16.2)
—
is_constructible_v<Ti, const Ui&> is true for all i, and
(16.3)
—
either sizeof...(Types) != 1, or (when Types... expands to T and UTypes... expands
to U) is_convertible_v<const tuple<U>&, T>, is_constructible_v<T, const tuple<U>&>,
and is_same_v<T, U> are all false.
The constructor is explicit if and only if is_convertible_v<const Ui&, Ti> is false for at least one
i.
template<class... UTypes> EXPLICIT constexpr tuple(tuple<UTypes...>&& u);
17
Effects: For all i, initializes the ith element of *this with std::forward<Ui>(get<i>(u)).
18
Remarks: This constructor shall not participate in overload resolution unless
(18.1)
—
sizeof...(Types) == sizeof...(UTypes), and
(18.2)
—
is_constructible_v<Ti, Ui&&> is true for all i, and
(18.3)
—
either sizeof...(Types) != 1, or (when Types... expands to T and UTypes... expands to
U) is_convertible_v<tuple<U>, T>, is_constructible_v<T, tuple<U>>, and is_same_v<T,
U> are all false.
The constructor is explicit if and only if is_convertible_v<Ui&&, Ti> is false for at least one i.
template<class U1, class U2> EXPLICIT constexpr tuple(const pair<U1, U2>& u);
19
Effects: Initializes the first element with u.first and the second element with u.second.
20
Remarks: This constructor shall not participate in overload resolution unless sizeof...(Types) == 2,
is_constructible_v<T0, const U1&> is true and is_constructible_v<T1, const U2&> is true.
21
The constructor is explicit if and only if is_convertible_v<const U1&, T0> is false or is_convert-
ible_v<const U2&, T1> is false.
§ 23.5.3.1
499
template<class U1, class U2> EXPLICIT constexpr tuple(pair<U1, U2>&& u);
22
Effects: Initializes the first element with std::forward<U1>(u.first) and the second element with
std::forward<U2>(u.second).
23
Remarks: This constructor shall not participate in overload resolution unless sizeof...(Types) == 2,
is_constructible_v<T0, U1&&> is true and is_constructible_v<T1, U2&&> is true.
24
The constructor is explicit if and only if is_convertible_v<U1&&, T0> is false or is_convertible_-
v<U2&&, T1> is false.
template<class Alloc>
tuple(allocator_arg_t, const Alloc& a);
template<class Alloc>
EXPLICIT tuple(allocator_arg_t, const Alloc& a, const Types&...);
template<class Alloc, class... UTypes>
EXPLICIT tuple(allocator_arg_t, const Alloc& a, UTypes&&...);
template<class Alloc>
tuple(allocator_arg_t, const Alloc& a, const tuple&);
template<class Alloc>
tuple(allocator_arg_t, const Alloc& a, tuple&&);
template<class Alloc, class... UTypes>
EXPLICIT tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&);
template<class Alloc, class... UTypes>
EXPLICIT tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&&);
template<class Alloc, class U1, class U2>
EXPLICIT tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
template<class Alloc, class U1, class U2>
EXPLICIT tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
25
Requires: Alloc shall meet the requirements for an Allocator (20.5.3.5).
26
Effects: Equivalent to the preceding constructors except that each element is constructed with uses-
allocator construction (23.10.8.2).
23.5.3.2
Assignment
[tuple.assign]
1
For each tuple assignment operator, an exception is thrown only if the assignment of one of the types in Types
throws an exception. In the function descriptions that follow, let i be in the range [0, sizeof...(Types))
in order, Ti be the ith type in Types, and Ui be the ith type in a template parameter pack named UTypes,
where indexing is zero-based.
tuple& operator=(const tuple& u);
2
Effects: Assigns each element of u to the corresponding element of *this.
3
Remarks: This operator shall be defined as deleted unless is_copy_assignable_v<Ti> is true for all i.
4
Returns: *this.
tuple& operator=(tuple&& u) noexcept(see below );
5
Effects: For all i, assigns std::forward<Ti>(get<i>(u)) to get<i>(*this).
6
Remarks: This operator shall not participate in overload resolution unless is_move_assignable_v<Ti>
is true for all i.
7
Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:
is_nothrow_move_assignable_v<Ti>
where Ti is the ith type in Types.
8
Returns: *this.
template<class... UTypes> tuple& operator=(const tuple<UTypes...>& u);
9
Effects: Assigns each element of u to the corresponding element of *this.
10
Remarks: This operator shall not participate in overload resolution unless sizeof...(Types) ==
sizeof...(UTypes) and is_assignable_v<Ti&, const Ui&> is true for all i.
11
Returns: *this.
§ 23.5.3.2
500
template<class... UTypes> tuple& operator=(tuple<UTypes...>&& u);
12
Effects: For all i, assigns std::forward<Ui>(get<i>(u)) to get<i>(*this).
13
Remarks: This operator shall not participate in overload resolution unless is_assignable_v<Ti&,
Ui&&> == true for all i and sizeof...(Types) == sizeof...(UTypes).
14
Returns: *this.
template<class U1, class U2> tuple& operator=(const pair<U1, U2>& u);
15
Effects: Assigns u.first to the first element of *this and u.second to the second element of *this.
16
Remarks: This operator shall not participate in overload resolution unless sizeof...(Types) == 2 and
is_assignable_v<T0&, const U1&> is true for the first type T0 in Types and is_assignable_v<T1&,
const U2&> is true for the second type T1 in Types.
17
Returns: *this.
template<class U1, class U2> tuple& operator=(pair<U1, U2>&& u);
18
Effects: Assigns std::forward<U1>(u.first) to the first element of *this and
std::forward<U2>(u.second) to the second element of *this.
19
Remarks: This operator shall not participate in overload resolution unless sizeof...(Types) == 2
and is_assignable_v<T0&, U1&&> is true for the first type T0 in Types and is_assignable_v<T1&,
U2&&> is true for the second type T1 in Types.
20
Returns: *this.
23.5.3.3
swap
[tuple.swap]
void swap(tuple& rhs) noexcept(see below );
1
Requires: Each element in *this shall be swappable with (20.5.3.2) the corresponding element in rhs.
2
Effects: Calls swap for each element in *this and its corresponding element in rhs.
3
Remarks: The expression inside noexcept is equivalent to the logical and of the following expressions:
is_nothrow_swappable_v<Ti>
where Ti is the ith type in Types.
4
Throws: Nothing unless one of the element-wise swap calls throws an exception.
23.5.3.4
Tuple creation functions
[tuple.creation]
1
In the function descriptions that follow, the members of a parameter pack X Types are denoted by Xi for i in
[0, sizeof...(X Types)) in order, where indexing is zero-based.
template<class... TTypes>
constexpr tuple<VTypes...> make_tuple(TTypes&&... t);
2
The pack VTypes is defined as follows. Let Ui be decay_t<Ti> for each Ti in TTypes. If Ui is a
specialization of reference_wrapper, then Vi in VTypes is Ui::type&, otherwise Vi is Ui.
3
Returns: tuple<VTypes...>(std::forward<TTypes>(t)...).
4
[ Example:
int i; float j;
make_tuple(1, ref(i), cref(j))
creates a tuple of type tuple<int, int&, const float&>.
— end example ]
template<class... TTypes>
constexpr tuple<TTypes&&...> forward_as_tuple(TTypes&&... t) noexcept;
5
Effects: Constructs a tuple of references to the arguments in t suitable for forwarding as arguments to
a function. Because the result may contain references to temporary variables, a program shall ensure
that the return value of this function does not outlive any of its arguments (e.g., the program should
typically not store the result in a named variable).
6
Returns: tuple<TTypes&&...>(std::forward<TTypes>(t)...).
§ 23.5.3.4
501
|
|