Как сделать шаблон специализированной функции другом какого-то класса? - PullRequest
0 голосов
/ 02 октября 2019

Я пытаюсь найти способ сделать функцию, которая является другом для данного класса. Эта функция является методом другого класса и является специализацией шаблона. Без специализации у меня есть следующий скомпилированный код в Visual Studio:

ClassA.h:

#pragma once
#include "classB.h"

class A
{
private:
    int data;
    void Operate();
public:
    A();
    ~A();
    template<class T> friend void B::DoSomething(const T& arg);
};

ClassB.h:

#pragma once

class B
{
private:
    int data;
    template<typename T> void DoSomething(const T& arg)
    {
        T copy = arg;
        copy.Operate();
        data = 3;
    };
/*
    template<> void DoSomething(const A& arg)
    {
        A copy = arg;
        copy.Operate();
        data = 4;
    };
*/

public:
    B();
    ~B();
};

ClassA.cpp:

#include "classA.h"

A::A()
{
    data = 1;
}

A::~A()
{
}

void A::Operate()
{
    data = 2;
}

ClassB.cpp:

#include "classB.h"

B::B()
{
    data = 1;
}

B::~B()
{
}

Как мне специализировать шаблон и сделать его другом вместо всего шаблона? Если это возможно, то где мне его разместить? Нужны ли где-нибудь предварительные декларации? Какие заголовки мне нужно включить и т. Д.? * 10101

Я попытался раскомментировать блок в classB.h и добавить #include "classA.h" поверх него. Я также попытался заменить строку template<class T> friend void B::DoSomething(const T& arg); в classA.h чем-то вроде template<> friend void B::DoSomething(const A& arg);. Ничего не помоглоОн отказывается компилировать.

Буду признателен за любую информацию!

1 Ответ

2 голосов
/ 02 октября 2019

Чтобы сделать B::DoSomething<int> другом A, используйте

friend void B::template DoSomething<int>(const int& arg);

Чтобы сделать B::DoSomething<A> другом A, используйте

friend void B::template DoSomething<A>(const A& arg);

Обратите внимание, чточтобы иметь возможность сделать это, DoSomething должен быть public членом B.

Дополнительная информация: Где и почему я должен указывать ключевые слова "template" и "typename"?

...