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

NAME
     std::transform - std::transform

Synopsis
	Defined in header <algorithm>
	template< class InputIt, class OutputIt, class UnaryOp >

	OutputIt  transform( InputIt first1, InputIt last1,	  (1) (constexpr
     since C++20)

			    OutputIt d_first, UnaryOp unary_op
	);
	template< class ExecutionPolicy,

		  class ForwardIt1, class ForwardIt2, class
	UnaryOp >
	ForwardIt2  transform(	ExecutionPolicy&&  policy,	     (2)  (since
     C++17)
			      ForwardIt1 first1, ForwardIt1
	last1,

			      ForwardIt2 d_first, UnaryOp
	unary_op );
	template< class InputIt1, class InputIt2,

		  class OutputIt, class BinaryOp >
	OutputIt  transform( InputIt1 first1, InputIt1 last1,	  (3) (constexpr
     since C++20)
	InputIt2 first2,

			    OutputIt d_first, BinaryOp binary_op
	);
	template< class ExecutionPolicy,

		  class ForwardIt1, class ForwardIt2,
		  class ForwardIt3, class BinaryOp >
	ForwardIt3 transform( ExecutionPolicy&& policy,
			      ForwardIt1  first1,  ForwardIt1	    (4)   (since
     C++17)
	last1,
			      ForwardIt2 first2,

			      ForwardIt3 d_first, BinaryOp
	binary_op );

	std::transform	applies  the given function to the elements of the given
     input
	range(s), and stores  the  result  in  an  output  range  starting  from
     d_first.

	1)  The  unary operation unary_op is applied to the elements of [first1,
     last1).
	If unary_op invalidates an iterator or modifies an element in any of the
     following
	ranges, the behavior is undefined:
	  * [first1, last1].
	  * The range of std::distance(first1, last1) + 1 elements starting from
     d_first.
	3) The binary operation binary_op is applied to pairs of  elements  from
     two ranges:
	[first1,  last1)  and another range of std::distance(first1, last1) ele-
     ments starting
	from first2.
	If binary_op invalidates an iterator or modifies an element  in  any  of
     the following
	ranges, the behavior is undefined:
	  * [first1, last1].
	  * The range of std::distance(first1, last1) + 1 elements starting from
     first2.
	  * The range of std::distance(first1, last1) + 1 elements starting from
     d_first.
	2,4) Same as (1,3), but executed according to policy.
	These overloads participate in overload resolution only if

	std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>    is    true.
     (until
										  C++20)
	std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>      is
     true. (since
										  C++20)

Parameters
	first1, last1 - the first range of elements to transform
	first2	       - the beginning of the second range of elements to trans-
     form
	d_first       - the beginning of the destination range, may be equal  to
     first1 or
			first2
	policy	       -  the  execution policy to use. See execution policy for
     details.
			unary operation function object that will be applied.

			The signature of the function should  be  equivalent  to
     the following:

			 Ret fun(const Type &a);
	unary_op      -
			The signature does not need to have const &.
			The  type   Type must be such that an object of type In-
     putIt can be
			dereferenced and then implicitly converted to  Type. The
     type Ret
			must be such that an object  of  type  OutputIt  can  be
     dereferenced and
			assigned a value of type Ret.
			binary operation function object that will be applied.

			The  signature	of  the function should be equivalent to
     the following:

			 Ret fun(const Type1 &a, const Type2 &b);
	binary_op     -
			The signature does not need to have const &.
			The types  Type1 and  Type2 must be such that objects of
     types
			InputIt1 and InputIt2 can be dereferenced and  then  im-
     plicitly
			converted  to	Type1  and  Type2 respectively. The type
     Ret must be
			such that an object of type OutputIt can be dereferenced
     and
			assigned a value of type Ret.

Type requirements
	-
	InputIt, InputIt1, InputIt2 must meet the requirements of LegacyInputIt-
     erator.
	-
	OutputIt must meet the requirements of LegacyOutputIterator.
	-
	ForwardIt1, ForwardIt2, ForwardIt3 must meet the requirements of
	LegacyForwardIterator.

Return value
	Output iterator to the element that  follows  the  last  element  trans-
     formed.

Complexity
	Given \(\scriptsize N\)N as std::distance(first1, last1):

	1,2) Exactly \(\scriptsize N\)N applications of unary_op.
	3,4) Exactly \(\scriptsize N\)N applications of binary_op.

Exceptions
	The overloads with a template parameter named ExecutionPolicy report er-
     rors as
	follows:

	  *  If  execution of a function invoked as part of the algorithm throws
     an exception
	    and ExecutionPolicy is one of the standard policies,  std::terminate
     is called.
	    For  any  other  ExecutionPolicy, the behavior is implementation-de-
     fined.
	  * If the algorithm fails to allocate memory, std::bad_alloc is thrown.

Possible implementation
				   transform (1)
	template<class InputIt, class OutputIt, class UnaryOp>
	constexpr //< since C++20
	OutputIt transform(InputIt first1, InputIt last1,
			   OutputIt d_first, UnaryOp unary_op)
	{
	    for (; first1 != last1; ++d_first, ++first1)
		*d_first = unary_op(*first1);

	    return d_first;
	}
				   transform (3)
	template<class InputIt1, class InputIt2,
		 class OutputIt, class BinaryOp>
	constexpr //< since C++20
	OutputIt transform(InputIt1 first1, InputIt1 last1, InputIt2 first2,
			   OutputIt d_first, BinaryOp binary_op)
	{
	    for (; first1 != last1; ++d_first, ++first1, ++first2)
		*d_first = binary_op(*first1, *first2);

	    return d_first;
	}

Notes
	std::transform does not guarantee in-order application	of  unary_op  or
     binary_op. To
	apply a function to a sequence in-order or to apply a function that mod-
     ifies the
	elements of a sequence, use std::for_each.

Example
     // Run this code

      #include <algorithm>
      #include <cctype>
      #include <iomanip>
      #include <iostream>
      #include <string>
      #include <utility>
      #include <vector>

      void print_ordinals(const std::vector<unsigned>& ordinals)
      {
	  std::cout << "ordinals: ";
	  for (unsigned ord : ordinals)
	      std::cout << std::setw(3) << ord << ' ';
	  std::cout << '\n';
      }

      char to_uppercase(unsigned char c)
      {
	  return std::toupper(c);
      }

      void to_uppercase_inplace(char& c)
      {
	  c = to_uppercase(c);
      }

      void unary_transform_example(std::string& hello, std::string world)
      {
	  // Transform string to uppercase in-place

	  std::transform(hello.cbegin(),  hello.cend(), hello.begin(), to_upper-
     case);
	  std::cout << "hello = " << std::quoted(hello) << '\n';

	  // for_each version (see Notes above)
	  std::for_each(world.begin(), world.end(), to_uppercase_inplace);
	  std::cout << "world = " << std::quoted(world) << '\n';
      }

      void binary_transform_example(std::vector<unsigned> ordinals)
      {
	  // Transform numbers to doubled values

	  print_ordinals(ordinals);

	  std::transform(ordinals.cbegin(), ordinals.cend(), ordinals.cbegin(),
			 ordinals.begin(), std::plus<>{});

	  print_ordinals(ordinals);
      }

      int main()
      {
	  std::string hello("hello");
	  unary_transform_example(hello, "world");

	  std::vector<unsigned> ordinals;
	  std::copy(hello.cbegin(), hello.cend(), std::back_inserter(ordinals));
	  binary_transform_example(std::move(ordinals));
      }

Output:
      hello = "HELLO"
      world = "WORLD"
      ordinals:  72  69  76  76  79
      ordinals: 144 138 152 152 158

	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  242 C++98	    unary_op and binary_op could not have side they can-
     not modify the
			   effects				      ranges in-
     volved

See also
	for_each	  applies a function to a range of elements
			  (function template)
	ranges::transform applies a function to a range of elements
	(C++20) 	  (niebloid)

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

home | help