Home > database >  Double template argument for a template function
Double template argument for a template function

Time:10-16

What would be a valid definition of this function to be called in main as the following?

foo<float, double>(sqrtfunction< float>, floatList);

I was wondering if it’s done with template classes, but isn't possible to do this without calling it as a member of a class?

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 a 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 << " ";
}

Output:

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:

I think user 463035818's answer resolved your problem.

But if you want to write a 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, ", "));
}
  • Related