home | help
std::tuple::tuple(3)	       C++ Standard Libary	    std::tuple::tuple(3)

NAME
     std::tuple::tuple - std::tuple::tuple

Synopsis
	Defined in header <tuple>
	constexpr   tuple();					   (1)	  (since
     C++11)
								    (condition-
     ally explicit)
								    (since
     C++11)
	tuple( const Types&... args );				(2)   (constexpr
     since C++14)
								    (condition-
     ally explicit)
	template<   class...   UTypes  >				  (since
     C++11)
	tuple( UTypes&&... args );				(3)   (constexpr
     since C++14)
								    (condition-
     ally explicit)
	template<   class...  UTypes  > 			    (4)   (since
     C++23)
	constexpr tuple( tuple<UTypes...>& other );		     (condition-
     ally explicit)
	template<   class...   UTypes  >				  (since
     C++11)
	tuple( const tuple<UTypes...>& other ); 		(5)   (constexpr
     since C++14)
								    (condition-
     ally explicit)
	template<   class...   UTypes  >				  (since
     C++11)
	tuple( tuple<UTypes...>&& other );			(6)   (constexpr
     since C++14)
								    (condition-
     ally explicit)
	template<   class...  UTypes  > 			    (7)   (since
     C++23)
	constexpr tuple( const tuple<UTypes...>&& other );	     (condition-
     ally explicit)
	template<  class  U1,  class  U2  >			     (8)  (since
     C++23)
	constexpr tuple( std::pair<U1, U2>& p );		     (condition-
     ally explicit)
	template<  class  U1,  class  U2  >				  (since
     C++11)
	tuple( const std::pair<U1, U2>& p );			(9)   (constexpr
     since C++14)
								    (condition-
     ally explicit)
	template<  class  U1,  class  U2  >				  (since
     C++11)
	tuple( std::pair<U1, U2>&& p ); 			(10)  (constexpr
     since C++14)
								    (condition-
     ally explicit)
	template<  class  U1,  class  U2  >			     (11) (since
     C++23)
	constexpr tuple( const std::pair<U1, U2>&& p ); 	     (condition-
     ally explicit)
	template<   tuple-like	UTuple	>			    (12)  (since
     C++23)
	constexpr tuple( UTuple&& u );				     (condition-
     ally explicit)
	tuple(	const  tuple&  other  )  =  default;		     (13) (since
     C++11)
	tuple( tuple&&	other  )  =  default;			    (14)  (since
     C++11)
	Allocator-extended constructors
	template<   class   Alloc  >					  (since
     C++11)
	tuple( std::allocator_arg_t, const Alloc& a );		(15)  (constexpr
     since C++20)
								    (condition-
     ally explicit)
	template< class Alloc >
								    (since
     C++11)
	tuple(	std::allocator_arg_t,  const Alloc& a,		 (16) (constexpr
     since C++20)
								    (condition-
     ally explicit)
	       const Types&... args );
	template< class Alloc, class... UTypes >
								    (since
     C++11)
	tuple( std::allocator_arg_t, const Alloc& a,		(17)  (constexpr
     since C++20)
								    (condition-
     ally explicit)
	       UTypes&&... args );
	template< class Alloc, class... UTypes >
								    (since
     C++23)
	constexpr  tuple( std::allocator_arg_t, const Alloc& a, (18) (condition-
     ally explicit)

			 tuple<UTypes...>& other );
	template< class Alloc, class... UTypes >
								    (since
     C++11)
	tuple( std::allocator_arg_t, const Alloc& a,		(19)  (constexpr
     since C++20)
								    (condition-
     ally explicit)
	       const tuple<UTypes...>& other );
	template< class Alloc, class... UTypes >
								    (since
     C++11)
	tuple(	std::allocator_arg_t,  const Alloc& a,		 (20) (constexpr
     since C++20)
								    (condition-
     ally explicit)
	       tuple<UTypes...>&& other );
	template< class Alloc, class... UTypes >
								    (since
     C++23)
	constexpr tuple( std::allocator_arg_t, const Alloc& a, (21)  (condition-
     ally explicit)

			 const tuple<UTypes...>&& other );
	template< class Alloc, class U1, class U2 >
								    (since
     C++23)
	constexpr  tuple( std::allocator_arg_t, const Alloc& a, (22) (condition-
     ally explicit)

			 std::pair<U1, U2>& p );
	template< class Alloc, class U1, class U2 >
								    (since
     C++11)
	tuple( std::allocator_arg_t, const Alloc& a,		(23)  (constexpr
     since C++20)
								    (condition-
     ally explicit)
	       const std::pair<U1, U2>& p );
	template< class Alloc, class U1, class U2 >
								    (since
     C++11)
	tuple(	std::allocator_arg_t,  const Alloc& a,		 (24) (constexpr
     since C++20)
								    (condition-
     ally explicit)
	       std::pair<U1, U2>&& p );
	template< class Alloc, class U1, class U2 >
								    (since
     C++23)
	constexpr tuple( std::allocator_arg_t, const Alloc& a, (25)  (condition-
     ally explicit)

			 const std::pair<U1, U2>&& p );
	template<  class  Alloc,  tuple-like  UTuple  > 		  (since
     C++23)
	constexpr tuple( std::allocator_arg_t, const Alloc& a, (26)  (condition-
     ally explicit)
	UTuple&& u );
	template< class Alloc >
								    (since
     C++11)
	tuple(	std::allocator_arg_t,  const Alloc& a,		 (27) (constexpr
     since C++20)

	       const tuple& other );
	template< class Alloc >
								    (since
     C++11)
	tuple( std::allocator_arg_t, const Alloc& a,		(28)  (constexpr
     since C++20)

	       tuple&& other );

	Constructs a new tuple.

	In the 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.

	1)  Default constructor. Value-initializes all elements, if any. The de-
     fault
	constructor is trivial if sizeof...(Types) == 0.
	  * This overload participates in overload resolution only if
	    std::is_default_constructible<Ti>::value is true for all i.
	  * The constructor is explicit if and only if Ti is not  copy-list-ini-
     tializable
	    from {} for at least one i.
	2)  Direct  constructor.  Initializes each element of the tuple with the
     corresponding
	parameter.
	  *  This  overload  participates  in  overload   resolution   only   if
     sizeof...(Types) >= 1
	    and std::is_copy_constructible<Ti>::value is true for all i.
	  *  This  constructor	is  explicit  if  and  only  if std::is_convert-
     ible<const Ti&,
	    Ti>::value is false for at least one i.
	3) Converting constructor. Initializes each element of	the  tuple  with
     the
	corresponding value in std::forward<UTypes>(args).
	  * This overload participates in overload resolution only if
	       * sizeof...(Types) == sizeof...(UTypes),
	       * sizeof...(Types) >= 1,
	       * std::is_constructible<Ti, Ui>::value is true for all i, and
	       * let D be
		 std::decay<U0>::type
		 (until C++20)
		 std::remove_cvref_t<U0>
		 (since C++20),
		    * if sizeof...(Types) == 1, then D is not std::tuple, other-
     wise,
		    *  if  sizeof...(Types)  == 2 or sizeof...(Types) == 3, then
     either D is
		      not std::allocator_arg_t, or T0 is std::allocator_arg_t.
	  * The constructor is explicit if and only  if  std::is_convertible<Ui,
     Ti>::value is
	    false for at least one i.

	  * This constructor is defined as deleted if the initialization of
	    any  element  that	is  a  reference  would  bind  it to a temporary
     (since C++23)
	    object.

	4-7) Converting constructor. Initializes each element of the tuple  with
     the
	corresponding element of other.

	Formally,  let	FWD(other)  be std::forward<decltype(other)>(other), for
     all i,
	initializes ith element of the tuple with std::get<i>(FWD(other)).

	  * This overload participates in overload resolution only if
	       * sizeof...(Types) == sizeof...(UTypes),
	       * std::is_constructible_v<Ti,  decltype(std::get<i>(FWD(other)))>
     is true for
		 all i, and
	       * either
		    * sizeof...(Types) is not 1, or
		    * (when Types... expands to T and UTypes... expands to U)
		      std::is_convertible_v<decltype(other),   T>,  std::is_con-
     structible_v<T,
		      decltype(other)>, and std::is_same_v<T, U> are all false.
	  * These constructors are explicit if and only if
	    std::is_convertible_v<decltype(std::get<i>(FWD(other))),   Ti>    is
     false for at
	    least one i.

	  * These constructors are defined as deleted if the initialization of
	    any  element  that	is  a  reference  would  bind  it to a temporary
     (since C++23)
	    object.

	8-11) Pair constructor. Constructs a 2-element tuple with  each  element
     constructed
	from the corresponding element of p.

	Formally,  let	FWD(p)	be std::forward<decltype(p)>(p), initializes the
     first element
	with	std::get<0>(FWD(p))    and    the    second	element     with
     std::get<1>(FWD(p)).

	  * This overload participates in overload resolution only if
	       * sizeof...(Types) == 2,
	       *  std::is_constructible_v<T0,  decltype(std::get<0>(FWD(p)))> is
     true, and
	       * std::is_constructible_v<T1,  decltype(std::get<1>(FWD(p)))>  is
     true.
	  * The constructor is explicit if and only if
	    std::is_convertible_v<decltype(std::get<0>(FWD(p))), T0> or
	    std::is_convertible_v<decltype(std::get<1>(FWD(p))), T1> is false.

	  * These constructors are defined as deleted if the initialization of
	    any  element  that	is  a  reference  would  bind  it to a temporary
     (since C++23)
	    object.

	12) tuple-like constructor. Constructs a tuple with  each  element  con-
     structed from
	the corresponding element of u.

	Formally, for all i, initializes ith element of the tuple with
	std::get<i>(std::forward<UTuple>(u)).

	  * This overload participates in overload resolution only if
	       * std::same_as<std::remove_cvref_t<UTuple>, std::tuple> is false,
	       * std::remove_cvref_t<UTuple> is not a specialization of
		 std::ranges::subrange,
	       *      sizeof...(Types)	   equals     std::tuple_size_v<std::re-
     move_cvref_t<UTuple>>,
	       *   std::is_constructible_v<Ti,	  decltype(std::get<i>(std::for-
     ward<UTuple>(u)))>
		 is true for all i, and
	       * either
		    * sizeof...(Types) is not 1, or
		    * (when Types... expands to T) std::is_convertible_v<UTuple,
     T> and
		      std::is_constructible_v<T, UTuple> are both false.
	  *  This constructor is defined as deleted if the initialization of any
     element that
	    is a reference would bind it to a temporary object.
	13) Implicitly-defined copy constructor. Initializes each element of the
     tuple with
	the corresponding element of other.
	  * This constructor is constexpr if every operation it performs is con-
     stexpr. For
	    the empty tuple std::tuple<>, it is constexpr.
	  * std::is_copy_constructible<Ti>::value must be true for all i, other-
     wise
	    the behavior is undefined
	    (until C++20)
	    the program is ill-formed
	    (since C++20).
	14) Implicitly-defined move constructor. For all i, initializes the  ith
     element of
	the tuple with std::forward<Ui>(std::get<i>(other)).
	  * This constructor is constexpr if every operation it performs is con-
     stexpr. For
	    the empty tuple std::tuple<>, it is constexpr.
	  * std::is_move_constructible<Ti>::value must be true for all i, other-
     wise
	    the behavior is undefined
	    (until C++20)
	    this overload does not participate in overload resolution
	    (since C++20).
	15-28)	Identical to (1-14) except each element is created by uses-allo-
     cator
	construction, that is, the Allocator object a is passed as an additional
     argument to
	the constructor of each element for  which  std::uses_allocator<Ui,  Al-
     loc>::value is
	true.

Parameters
	args  - values used to initialize each element of the tuple
	other - the tuple of values used to initialize each element of the tuple
	p     - the pair of values used to initialize both elements of the 2-tu-
     ple
	u      - the tuple-like object of values used to initialize each element
     of the tuple
	a     - the allocator to use in uses-allocator construction

Notes
	Conditionally-explicit constructors make it possible to construct a  tu-
     ple in
	copy-initialization context using list-initialization syntax:

      std::tuple<int, int> foo_tuple()
      {
	  // return {1, -1};		 // Error before N4387
	  return std::make_tuple(1, -1); // Always works
      }

	Note  that  if some element of the list is not implicitly convertible to
     the
	corresponding element of the target tuple, the constructors  become  ex-
     plicit:

      using namespace std::chrono;
      void launch_rocket_at(std::tuple<hours, minutes, seconds>);

      launch_rocket_at({hours(1), minutes(2), seconds(3)}); // OK
      launch_rocket_at({1,  2,	3}); // Error: int is not implicitly convertible
     to duration
      launch_rocket_at(std::tuple<hours, minutes, seconds>{1, 2, 3}); // OK

Example
     // Run this code

      #include <iomanip>
      #include <iostream>
      #include <memory>
      #include <string>
      #include <string_view>
      #include <tuple>
      #include <type_traits>
      #include <vector>

      // helper function to print a vector to a stream
      template<class Os, class T>
      Os& operator<<(Os& os, std::vector<T> const& v)
      {
	  os << '{';
	  for (auto i{v.size()}; const T& e : v)
	      os << e << (--i ? "," : "");
	  return os << '}';
      }

      template<class T>
      void print_single(T const& v)
      {
	  if constexpr (std::is_same_v<T, std::decay_t<std::string>>)
	      std::cout << std::quoted(v);
	  else if constexpr (std::is_same_v<std::decay_t<T>, char>)
	      std::cout << "'" << v << "'";
	  else
	      std::cout << v;
      }

      // helper function to print a tuple of any size
      template<class Tuple, std::size_t N>
      struct TuplePrinter
      {
	  static void print(const Tuple& t)
	  {
	      TuplePrinter<Tuple, N - 1>::print(t);
	      std::cout << ", ";
	      print_single(std::get<N - 1>(t));
	  }
      };

      template<class Tuple>
      struct TuplePrinter<Tuple, 1>
      {
	  static void print(const Tuple& t)
	  {
	      print_single(std::get<0>(t));
	  }
      };

      template<class... Args>
      void print(std::string_view message, const std::tuple<Args...>& t)
      {
	  std::cout << message << " (";
	  TuplePrinter<decltype(t), sizeof...(Args)>::print(t);
	  std::cout << ")\n";
      }
      // end helper function

      int main()
      {
	  std::tuple<int, std::string, double> t1;
	  print("Value-initialized, t1:", t1);

	  std::tuple<int, std::string, double> t2{42, "Test", -3.14};
	  print("Initialized with values, t2:", t2);

	  std::tuple<char, std::string, int> t3{t2};
	  print("Implicitly converted, t3:", t3);

	  std::tuple<int, double> t4{std::make_pair(42, 3.14)};
	  print("Constructed from a pair, t4:", t4);

	  // given Allocator my_alloc with a single-argument constructor
	  // my_alloc(int); use my_alloc(1) to allocate 5 ints in a vector
	  using my_alloc = std::allocator<int>;
	  std::vector<int, my_alloc> v{5, 1, my_alloc{/* 1 */}};

	  // use my_alloc(2) to allocate 5 ints in a vector in a tuple
	  std::tuple<int, std::vector<int, my_alloc>, double> t5
	      {std::allocator_arg, my_alloc{/* 2 */}, 42, v, -3.14};
	  print("Constructed with allocator, t5:", t5);
      }

Possible output:
      Value-initialized, t1: (0, "", 0)
      Initialized with values, t2: (42, "Test", -3.14)
      Implicitly converted, t3: ('*', "Test", -3)
      Constructed from a pair, t4: (42, 3.14)
      Constructed with allocator, t5: (42, {1,1,1,1,1}, -3.14)

	Defect reports

	The following behavior-changing defect	reports  were  applied	retroac-
     tively to
	previously published C++ standards.

	   DR	  Applied  to	      Behavior as published		 Correct
     behavior
	LWG 2510 C++11	    default constructor was implicit	 made condition-
     ally-explicit
			    constructor of 1-tuple might
	LWG 3121 C++11	    recursively check the constraints;	 furtherly  con-
     strained
			    allocator_arg_t argument brought	 the constructor
			    ambiguity
			    the uses-allocator constructor
	LWG 3158 C++11	    corresponding			 made condition-
     ally-explicit
			    to default constructor was implicit
	LWG  3211  C++11      whether the default constructor of   require to be
     trivial
			    tuple<> is trivial was unspecified
	N4387	 C++11	    some constructors were explicit,	 most  construc-
     tors made
			    preventing	useful behavior 	  conditionally-
     explicit
			    tuple-like constructor may
	LWG 4045 C++23	    potentially create dangling 	 made defined as
     deleted
			    references

See also
	operator=	 assigns the contents of one tuple to another
			 (public member function)
	make_tuple	 creates a tuple object of the type defined by the argu-
     ment types
	(C++11) 	 (function template)
	tie		 creates a tuple of lvalue references or unpacks a tuple
     into
	(C++11) 	 individual objects
			 (function template)
	forward_as_tuple creates a tuple of forwarding references
	(C++11) 	 (function template)
	constructor	 constructs new pair
			 (public member function of std::pair<T1,T2>)

http://cppreference.com 	   2024.06.10		    std::tuple::tuple(3)

home | help