Nano Hash - криптовалюты, майнинг, программирование

Оператор перегрузки‹‹ для класса шаблона. Невозможно получить приватных участников даже с ключевым словом друга

Я пытаюсь создать класс Set (используя шаблон). Проблема, которую я получаю, заключается в том, что я пытаюсь перегрузить оператор‹‹. Я попытался определить свою функцию как друга класса Set, но это не сработало. Я получил эту ошибку: ошибка: 'std::set, std::allocator > Set::m_set' является частным

Вот мой код:

#ifndef GUARD_set_h
#define GUARD_set_h

#include <iostream>
#include <array>
#include <vector>
#include <set>
#include <string>

using namespace std;

template <class T>
class Set
{ 

public:
Set() {} // est ce vraiment requis de l'écrire ? je pense qu oui mais a verif ou copy ?

Set(const T arr[], size_t arr_sz) // voir si operator= n est pas mieu ou copy ?
{
    for(size_t i = 0; i < arr_sz; ++i)
        m_set.insert(arr[i]);
}

Set(const vector<T>& vec)
{
    for(size_t i = 0; i < vec.size(); ++i)
        m_set.insert(vec[i]);
}

Set(const set<T>& st) 
{
    m_set = st;
}

Set(const Set& set_to_copy)
{
    m_set = set_to_copy.m_set;
}



void insert(const T& elem)
{
    m_set.insert(elem);
}

void remove(const T& elem)
{
    m_set.erase(elem);
}

size_t cardinality() const 
{
    return m_set.size();
}

bool isEmpty() const 
{
    return m_set.empty();
}

/** DEBUT OPERATORS **/

Set& operator +=(const Set& st)
{
    for (typename set<T>::iterator it = st.m_set.begin(); it != st.m_set.end(); ++it)
        m_set.insert(*it);
    return *this;
}


template<class U> friend ostream& operator<<(ostream &, const Set<T> &);

private:
set<T> m_set;
};


/** Non-Member Operators **/
template <typename T>
Set<T> operator+(Set<T> st1, const Set<T>& st2) // Set Union
{
    Set<T> set_to_copy(st1);
    set_to_copy += st2;
    return set_to_copy;
}

template <typename T>
Set<T> operator -(Set<T> st1, const Set<T>& st2) // Union Complement
{
    Set<T> set_to_copy(st1);
    set_to_copy -= st2;
    return set_to_copy;
}

template <class T>
ostream& operator<<(ostream &out, const Set<T> &st)
{
    for (typename set<T>::iterator it = st.m_set.begin(); it != st.m_set.end(); ++it)
        out << ' ' << *it;
    cout << '\n';
    return out;
}
#endif

Кажется, проблема в том, что я пытаюсь получить доступ к распределителю из класса набора по умолчанию, но я действительно не знаю, где я пытаюсь это использовать... Кто-нибудь знал, как правильно это использовать? Должен ли я переопределить новый распределитель? (Если возможно, я хотел бы сохранить эту организацию кода (это школьная работа, поэтому у меня есть критерии, которые нужно уважать:/) Я новичок в С++ и никогда раньше не использовал шаблон:/Извините, ребята, за мой приблизительный английский, и я уже благодарю вас за помощь :)

16.12.2013

Ответы:


1

Вам нужно изменить друга из:

template<class U> friend ostream& operator<<(ostream &, const Set<T> &);

to

// use Set<U> instead of Set<T>
template<class U> friend ostream& operator<<(ostream &, const Set< U > &);//U instead of T

потому что, когда вы создаете оператор друга с Set<T> вместо Set<U> и имеете экземпляр Set<int> (например), вы конкретно ссылаетесь на operator << для int:

ostream& operator<<(ostream &, const Set<int> &){}

и шаблонная версия полностью отличается от приведенной выше:

template <class T>
ostream& operator<<(ostream &, const Set<T> &){}

Изменить: это зависит от того, что вы хотите, если вы хотите сделать друга оператором, специфичным для вашего типа T, затем используйте нужно использовать Set<T> и объявить оператор для вашего типа T (int, float или любой другой тип, который вы создали Установить и использовать оператор ‹‹), а не шаблонную версию. Если вы хотите сделать шаблонную версию другом, вам нужно использовать Set<U>

16.12.2013
  • Предостережение состоит в том, что это делает все экземпляры шаблона оператора друзьями любого экземпляра шаблона класса Set. 16.12.2013

  • 2

    Первая проблема, которая у вас есть, это то, что оператор не тот. Вы не хотите, чтобы оператор был шаблоном типа U, где U не может быть выведен, возможно, вы имели в виду, что вторым аргументом будет Set<U>, а не Set<T>.

    При этом вам, вероятно, лучше вообще не дружить с оператором шаблона, а скорее дружить с нешаблонной функцией, которую вы можете определить внутри определения класса.

    template <typename T>
    class Set {
    //...
        friend std::ostream& operator<<(std::ostream& o, const Set& s) { ... }
    };
    

    Что, учитывая, что все функции-члены определены встроенными, не должно быть проблемой.

    16.12.2013

    3

    Спасибо, ребята, что так быстро ответили :) Переходим на это

    friend ostream& operator<<(ostream &, const Set<T> &);`
    

    не работает в моем случае, потому что (я думаю) мне нужно определить оператор‹‹` как функцию, не являющуюся членом. Но другое предложение, кажется, работает нормально:

    template<class U> friend ostream& operator<<(ostream &, const Set<U> &);
    
    16.12.2013
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..