C++20標準ライブラリstd::destructible<T>
コンセプトに関するメモ。
ある型T
が「例外送出なしにデストラクト可能」と制約(constraint)するコンセプト。デストラクタは既定で暗黙のnothrow指定が行われるため*1、明示的にnothrow(false)
指定を行わない限りあらゆるオブジェクト型が満たすコンセプトとなる。*2
std::destructible
コンセプトは、標準ヘッダ <concepts> 提供のオブジェクト関連コンセプトにより直接/間接的に包摂(subsume)される。
std::constructible_from
std::default_initializable
std::move_constructible
std::copy_constructible
std::movable
std::copyable
std::semiregular
std::regular
C++20 18.4.10, 18.4.11より引用(下線部は強調)。
1 The
destructible
concept specifies properties of all types, instances of which can be destroyed at the end of their lifetime, or reference types.template<class T> concept destructible = is_nothrow_destructible_v<T>;2 [Note: Unlike the Cpp17Destructible requirements (Table 32), this concept forbids destructors that are potentially throwing, even if a particular invocation of the destructor does not actually throw. -- end note]
1 The
constructible_from
concept constrains the initialization of a variable of a given type with a particular set of argument types.template<class T, class... Args> concept constructible_from = destructible<T> && is_constructible_v<T, Args...>;
2016年頃のC++ Ranges拡張PDTS*3時点でも、Destructibleコンセプト*4はオブジェクトコンセプトにおける最も基本的なコンセプトと説明されていた。(PDF)N4622より一部引用(下線部は強調)。
19.4 Object concepts
1 This section describes concepts that specify the basis of the value-oriented programming style on which the library is based.19.4.1 Concept Destructible
1 TheDestructible
concept is the base of the hierarchy of object concepts. It specifies properties that all such object types have in common.template <class T> concept bool Destructible() { return requires (T t, const T ct, T* p) { { t.~T() } noexcept; /*(snip)*/ }; }(snip)
19.4.2 Concept Constructible
1 TheConstructible
concept is used to constrain the type of a variable to be either an object type constructible from a given set of argument types, or a reference type that can be bound to those arguments.template <class T, class ...Args> concept bool __ConstructibleObject = Destructible<T>() && requires (Args&& ...args) { /*(snip)*/ }; template <class T, class ...Args> concept bool Constructible() { return __ConstructibleObject<T, Args...> || /*(snip)*/ }
関連URL
- c++ - Why does std::constructible_from require destructible? - Stack Overflow
- C++標準コンセプトの名前付けガイドライン - yohhoyの日記
- https://github.com/yohhoy/cpp-concepts
*1:C++20 14.5/p8: "The exception specification for an implicitly-declared destructor, or a destructor without a noexcept-specifier, is potentially-throwing if and only if any of the destructors for any of its potentially constructed subobjects is potentially-throwing or the destructor is virtual and the destructor of any virtual base class is potentially-throwing."
*2:参照型(reference type)はオブジェクト型(object type)ではないが(C++20 6.8.1/p8)、std::is_nothrow_destructible メタ関数の定義より std::destructible コンセプトを満たす。(cv修飾された)void 型/関数型/要素数未定の配列型は、std::destructible コンセプトを満たさない。
*3:Preliminary Draft Technical Specification
*4:検討段階におけるコンセプト関連の言語仕様は、C++20現在のコンセプト仕様とは異なっている。またコンセプト命名規則はその後の(PDF)P1754R1採択により Destructible→destructible/Constructible→constructible_from へと変更されている。