template do for_each

0

tworząc template, chciałbym uniknąć pisania w pętli "for_each" print<int> lub print<string> wolałbym żeby tam stało samo słowo print

// (Debian 10.2.1-6) Code::Blocks 20.03 -std=c++17 or higher
// g++ -Wall -fexceptions -g -std=c++17 -c main.cpp -o main.o

#include <iostream>
#include <algorithm> // for_each

using namespace std;

template<typename T>
void print(T const& x) {
    cout<<x<<' ';
}

int main()
{
    int tab[] = {21, 20, 33, 43, 15, 36, 777, 18, 9, 210};
    for_each(begin(tab),end(tab), [](const int &x){std::cout << x << " ";}  );
    cout<<'\n';
    for_each(rbegin(tab),rend(tab), print<int>);
    cout<<'\n';

    string SolarSystem[] = { "Sun", "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto" };
    for_each(begin(SolarSystem),end(SolarSystem), print<string>);
    cout<<'\n';

    std::for_each(begin(SolarSystem),end(SolarSystem), [](const auto& value) {
        print(value);
    });

    return 0;
}


4

Problemem jest moment w którym następuje dopasowanie szablonu.
W twojej wersji używasz funkcji for_each i dla argument print nie ma mechanizmu, który pozwałaby na detekcję typu tego szablonu.
Dla szablony funkcji detekcja typu funkcji następuje przy próbie wywołąnia funkcji i podania argumentów (tu nie podajesz arguemtów print).

Ergo można zrobić tak:

struct print {
    template <typename T>
    void operator()(T const& x)
    {
        cout << x << ' ';
    }
};

int main()
{
    int tab[] = { 21, 20, 33, 43, 15, 36, 777, 18, 9, 210 };
    for_each(begin(tab), end(tab), [](const int& x) { std::cout << x << " "; });
    cout << '\n';
    for_each(rbegin(tab), rend(tab), print{});
    cout << '\n';

    string SolarSystem[] = { "Sun", "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto" };
    for_each(begin(SolarSystem), end(SolarSystem), print{});
    cout << '\n';

    std::for_each(begin(SolarSystem), end(SolarSystem), [](const auto& value) {
        print{}(value);
    });

    return 0;
}

https://godbolt.org/z/vdsx8E1of

Ale estetyka tego jest koślawa.

Można próbować to poprawić tak:
https://godbolt.org/z/dW8eYzxf6
ale to mi się jeszcze bardziej nie podoba.

3

W tym konkretnym przypadku możesz użyć też lambdy + auto.

auto print = [](auto const& x){cout<<x<<' ';};
2

https://godbolt.org/z/77q36sfan

#include <string>
#include <ranges>
#include <fmt/ranges.h>

int main()
{
    int tab[] = {21, 20, 33, 43, 15, 36, 777, 18, 9, 210};
    std::string SolarSystem[] = { "Sun", "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto" };

    fmt::print("{}\n", tab);
    fmt::print("{}\n", fmt::join(tab, " "));
    fmt::print("{}\n", SolarSystem);

    fmt::print("{}\n", tab | std::views::reverse );
    fmt::print("{}\n", fmt::join(SolarSystem | std::views::reverse, " --> "));
    return 0;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1