Дружественные функции

186
10 мая 2018, 07:36

Есть класс, в котором объявлена дружественная функция, я хочу её определить тут же, т.е. не выносить определение в .cpp файл, а определить её в самом классе. Этого почему-то не получается, один из аргументов является типом класса и в определении функции я не могу получить доступ к его приватным данным. Как это можно сделать?

#pragma once
#include <iterator>
template <typename T>
class CIterator
{
public:
    using self_type = CIterator;
    using value_type = T;
    using reference = T&;
    using pointer = T*;
    using iterator_category = std::random_access_iterator_tag;
    //      Properties for all category iterator
    //Copy and copy-assignable by compiller
    //Constructors in private part
    const self_type& operator++() // Pre-increment
    {
        m_p++;
        return *this;
    }
    const self_type operator++(int) //Post-increment
    {
        auto tmp = *this;
        m_p++;
        return tmp;
    }
    ~CIterator() = default;
    //------------------------------------
    //      Input\output Iterator
    //operator-> by compiller
    bool operator==(const self_type& p) const
    {
        return m_p == p.m_p;
    }
    bool operator!=(const self_type& p) const
    {
        return !(*this == p);
    }
    reference operator*() const
    {
        return *m_p;
    }
    //------------------------------------
    //      Bidirectional Iterator
    const self_type& operator--()
    {
        m_p--;
        return *this;
    }
    const self_type operator--(int)
    {
        auto tmp = *this;
        m_p--;
        return tmp;
    }
    //------------------------------------
    //      Random Access Iterator
    const self_type& operator+=(ptrdiff_t size)
    {
        m_p += size;
        return *this;
    }
    const self_type& operator-=(ptrdiff_t size)
    {
        return *this += -size;
    }
    friend const self_type operator+(ptrdiff_t size, const self_type& p) //Can't define
    {
    /*
        Can't do, somethink like this, because "copy.m_p" not in scope, don'y know why.
        Similary to the other 4 friendly fucntion bellow.
        self_type copy = p;
        return copy.m_p + size;
    */
    }
    const self_type operator+(ptrdiff_t size)
    {
        return *this += size;
    }
    const self_type operator-(ptrdiff_t size)
    {
        return *this -= size;
    }
    const self_type operator-(const self_type& p)
    {
        auto copy = *this;
        copy.m_p -= p.m_p;
        return copy;
    }
    friend bool operator<=(const self_type& left, const self_type& right);
    friend bool operator>=(const self_type& left, const self_type& right);
    friend bool operator>(const self_type& left, const self_type& right);
    friend bool operator<(const self_type& left, const self_type& right);
    reference operator[](size_t i) const
    {
        return m_p[i];
    }
    //------------------------------------
private:
    CIterator()
        : m_p{ nullptr }
    {
    }
    CIterator(pointer p)
        : m_p{ p }
    {
    }
    pointer m_p;
};

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

Answer 1

"Дружественность" не означает особого качества функции-члена класса, а отношение к внешней, по отношению к данному классу, функции (глобальной или члену другого класса), поэтому вопрос о возможности определения функции в теле класса, членом которой она не является, не имеет смысла. Дружественная функция (по отношению к заданному классу), означает, что эта функция имеет доступ ко всем закрытым и защищенным компонентам этого класса

Если нужно описать функцию в заголовке (.h) в котором определено тело класса, это можно сделать по следующей схеме:

//SomeClass.h
class SomeClass;
void someGlobalFunc(SomeClass *sc);
class SomeClass
{
friend void someGlobalFunc(SomeClass *sc);
void somePrivateFunc() {
//TODO: add your code here
}
int _n;
};

void someGlobalFunc(SomeClass *sc) {
sc->somePrivateFunc();
sc->_n = 0;
}

Для шаблонного класса соответственно шаблонная глобальная функция:

template <typename T>
void someGlobalFunc(SomeClass<T> *sc) {
//...
}
READ ALSO
Использовать Cuda в существующем проекте

Использовать Cuda в существующем проекте

Мне по диплому нужно оптимизировать алгоритм (resize) библиотеки Magick++ при помощи Cuda

208
Добрый день! есть todo List .а localStorage не работает до конца) Что не так? заранее благодарю за помощь!

Добрый день! есть todo List .а localStorage не работает до конца) Что не так? заранее благодарю за помощь!

Вы не показали (не написали?) код, который использует элементы загруженного массивa todos для создания DOM-элементов во время загрузки страницы...

195
По клику на метку отображать поля из json

По клику на метку отображать поля из json

По клику нужно отображать поля принадлежащие этой ссылке(метке на карте)Отображаю только Id метки, нужно вытащить остальные, objectManager

210