std::is_con...onstructible(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

okay bestie, this page is called std::is_con...onstructible(3) and it lives in the C++ Standard Libary manual β€” yes, the title is truncated like that, and we’re about to make type traits make sense πŸ’…βœ¨

🌸 NAME 🌸

std::is_constructible, std::is_trivially_constructible, std::is_nothrow_constructible β€” the iconic trio, fr fr.

✨ Synopsis ✨

Defined in header <type_traits>, and the signatures are giving template realness:

Defined in header <type_traits>
template< class T, class... Args > (1) (since C++11)
struct is_constructible;
template< class T, class... Args > (2) (since C++11)
struct is_trivially_constructible;
template< class T, class... Args > (3) (since C++11)
struct is_nothrow_constructible;
  1. (1) β€” If T is an object or reference type and the variable definition T obj(std::declval<Args>()...); is well-formed, it provides the member constant value equal to true. In all other cases, value is false.

For the purposes of this check, the variable definition is never interpreted as a function declaration, and the use of std::declval is not considered an odr-use.

Access checks are performed as if from a context unrelated to T and any of the types in Args. Only the validity of the immediate context of the variable definition is considered.

  1. (2) β€” Same as (1), but the variable definition does not call any operation that is not trivial. For the purposes of this check, the call to std::declval is considered trivial.
  2. (3) β€” Same as (1), but the variable definition is noexcept.
🚨 undefined behavior alert, bestie β€” these are not a vibe:
  • If T or any type in the parameter pack Args is not a complete type, (possibly cv-qualified) void, or an array of unknown bound, the behavior is undefined.
  • If an instantiation of a template above depends, directly or indirectly, on an incomplete type, and that instantiation could yield a different result if that type were hypothetically completed, the behavior is undefined.
  • If the program adds specializations for any of the templates described on this page, the behavior is undefined.

πŸ’– Member constants πŸ’–

  • value β€” true if T is constructible from Args..., false otherwise. [static] (public static member constant)

πŸŽ€ Member functions πŸŽ€

  • operator bool β€” converts the object to bool, returns value (public member function)
  • operator() β€” returns value (C++14) (public member function)

πŸ¦‹ Member types πŸ¦‹

  • value_type β€” bool
  • type β€” std::integral_constant<bool, value>

🌈 Notes 🌈

In many implementations, is_nothrow_constructible also checks if the destructor throws because it is effectively noexcept(T(arg)). Same applies to is_trivially_constructible, which, in these implementations, also requires that the destructor is trivial: GCC bug 51452, LWG issue 2116.

πŸ“ Example πŸ“

// Run this code

#include <iostream>
#include <type_traits>

class Foo
{
    int v1;
    double v2;
public:
    Foo(int n) : v1(n), v2() {}
    Foo(int n, double f) noexcept : v1(n), v2(f) {}
};

int main()
{
    auto is = [](bool o) { return (o ? "\t" "is " : "\t" "isn't "); };
    std::cout << "Foo ...\n"
              << is(std::is_trivially_constructible_v<Foo, const Foo&>)
              << "Trivially-constructible from const Foo&\n"
              << is(std::is_trivially_constructible_v<Foo, int>)
              << "Trivially-constructible from int\n"
              << is(std::is_constructible_v<Foo, int>)
              << "Constructible from int\n"
              << is(std::is_nothrow_constructible_v<Foo, int>)
              << "Nothrow-constructible from int\n"
              << is(std::is_nothrow_constructible_v<Foo, int, double>)
              << "Nothrow-constructible from int and double\n";
}

Output ✨

Foo ...
    is Trivially-constructible from const Foo&
    isn't Trivially-constructible from int
    is Constructible from int
    isn't Nothrow-constructible from int
    is Nothrow-constructible from int and double

πŸ‘‘ See also πŸ‘‘

  • is_default_constructible β€” checks if a type has a default constructor (C++11) (class template)
  • is_trivially_default_constructible β€” checks if a type has a default constructor (C++11) (class template)
  • is_nothrow_default_constructible β€” checks if a type has a default constructor (C++11) (class template)
  • is_copy_constructible β€” checks if a type has a copy constructor (C++11) (class template)
  • is_trivially_copy_constructible β€” checks if a type has a copy constructor (C++11) (class template)
  • is_nothrow_copy_constructible β€” checks if a type has a copy constructor (C++11) (class template)
  • is_move_constructible β€” checks if a type can be constructed from an rvalue reference (C++11) (class template)
  • is_trivially_move_constructible β€” checks if a type can be constructed from an rvalue reference (C++11) (class template)
  • is_nothrow_move_constructible β€” checks if a type can be constructed from an rvalue reference (C++11) (class template)
  • constructible_from β€” specifies that a variable of the type can be constructed from or bound to a set of argument types (C++20) (concept)

k bye bestie πŸ’– this page is signed off from http://cppreference.com, version 2024.06.10, and the page std::is_con...onstructible(3) β€” go be constructible, or don’t, we don’t judge 🫢 periodt.

πŸ“¦ where this page comes from