What would be a valid definition of this function to be called in main as this:
- foo<float,double>(sqrtfunction< float> , floatList);
I was wondering if its done with Template classes but isn't possible to do this without calling it as a member of a class ?
Edit:
foo is a function which calls sqrtfunction which applies the sqrtfunction to every element in the "floatList" and returns the list in type of float in this case (type of the sqrtfunction). Whereas the output of foo is saved in vector instance of type double.
CodePudding user response:
What you describe sounds like std::transform
:
#include <vector>
#include <algorithm>
#include <cmath>
#include <iostream>
int main() {
std::vector<float> x{1,2,3,4,5};
std::vector<double> y(x.size());
auto sqrt = [](double x){ return std::sqrt(x);};
std::transform(x.begin(),x.end(),y.begin(),sqrt);
for (const auto& elem : y) std::cout << elem << " ";
}
1 1.41421 1.73205 2 2.23607
Generally, std::transform
works with any unary operation that transforms one element to another and assigns the transformed elements to the range starting at y.begin()
. The conversion from float
to double
takes place when the algorithm passes elements of x
to the lambda (and because it calls double std::sqrt(double)
, the result is double
).
CodePudding user response:
ITNOA
I think https://stackoverflow.com/a/69468033/1539100 is resolved your problem.
But if you want to write template function you can write something like this
#include <cmath>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <functional>
template <typename T>
T my_sqrt(T value)
{
return std::sqrt(value);
}
template <typename I, typename ElementType>
auto sqrt_function(std::function<I(I)> sqrt_func, const std::vector<I>& elements) -> std::vector<ElementType>
{
std::vector<ElementType> results;
std::transform(elements.cbegin(), elements.cend(), std::back_inserter(results), sqrt_func);
return results;
}
int main()
{
std::vector<double> results = sqrt_function<float, double>(my_sqrt<float>, std::vector<float>(10, 9.f));
std::copy(results.cbegin(), results.cend(), std::ostream_iterator<double>(std::cout, ", "));
}
And if you want to use template template parameter you can modify above code like below
template <typename I, template<typename> class List, typename ElementType>
auto sqrt_function(std::function<I(I)> sqrt_func, const List<I>& elements) -> std::vector<ElementType>
{
std::vector<ElementType> results;
std::transform(elements.cbegin(), elements.cend(), std::back_inserter(results), sqrt_func);
return results;
}
int main()
{
std::vector<double> results = sqrt_function<float, std::vector, double>(my_sqrt<float>, std::vector<float>(10, 9.f));
std::copy(results.cbegin(), results.cend(), std::ostream_iterator<double>(std::cout, ", "));
}