Не перегруженная функция C ++, которая может печатать вектор и вектор векторов? - PullRequest
0 голосов
/ 19 февраля 2020

Рассмотрим следующую перегруженную функцию, которая может печатать 1d-вектор и вектор-вектор нескольких типов, таких как strings, ints, doubles et c.

template<typename T>
void p(const vector<vector<T>>& vec) {
    int count = 0;
    for (vector<T> innerVec: vec) {
        cout << count++ << ": ";
        for (T e :innerVec) {
            cout << e << ' ';
        }
        cout << '\n';
    }
    cout << '\n';
}


template<typename T>
void p(const vector<T>& vec) {
    for (T e: vec) {
        cout << e << ' ';
    }
    cout << '\n';
}

Можно ли как-нибудь объединить эти две функции в 1? Я пытался использовать SFINAE и диспетчеризацию тегов, но все решения, которые я мог придумать, нуждаются в макросе или нескольких функциях, и я не хочу этого.

Я знаю, что вопрос может показаться странным, поскольку мое решение работает, но я предпочитаю иметь только одну функцию в моем коде. Это потому, что я хочу реализовать функцию, которая может обнаруживать, передаю ли я карту, вектор, вектор векторов, unordered_set, multimap и т. Д. c, и просто печатать эту структуру данных STL и иметь одну перегруженную функцию для каждой специализации: немного раздражает, поскольку это становится большим быстро.

Ответы [ 2 ]

1 голос
/ 19 февраля 2020

Я ответил на аналогичный вопрос сегодня. Проверьте это там: { ссылка }

Вставьте решение здесь:

Это должно работать для вашего случая. Обратите внимание, что я использую черту, реализованную здесь в этом удивительном решении @ Jarod42 { ссылка }.

template<template<typename ...> typename C, typename D, typename ... Others>
void foo(const C<D, Others...> &object)
{
    if constexpr(is_iterable<D>::value)
    {
       for(const auto& v : object)
       {
           for (const auto& w : v)
           {...}
       }
    }
    else
    {
       for (const auto& w : object)
       {...}
    }
}

Live Code

0 голосов
/ 19 февраля 2020

Да, но вам нужен дополнительный параметр, чтобы отличить guish внутренний от внешнего регистра

#include <vector>
#include <iostream>

struct counting_prefix {
    void call() { std::cout << count++ << ": "; }
    int count = 0;
};

struct no_prefix {
    void call() { }
};

template<typename T, typename Prefix = no_prefix>
void p(const T& e, Prefix prefix = {}) {
    prefix.call();
    std::cout << e << ' ';
}

template<typename T, typename Prefix = no_prefix>
void p(const std::vector<T>& vec, Prefix prefix = {}) {
    for (const T& e: vec) {
        prefix.call();
        p(e);
    }
    std::cout << '\n';
}

int main() {
    std::vector<std::vector<double>> stuff = { { 1., 2. }, { 3., 4. } };
    p(stuff, counting_prefix{});
}

Посмотреть вживую

...