FANDOM


Załóżmy, że mamy szablon klasy taki jak poniżej:

template<typename typ>
class Test
{
private:
	int a;
	typ b;
public:
	Test() { a = 10; }
};

i dla każdego typu typ chcemy mieć szablon funkcji, która bedzie zmieniała wartość składowej a oraz drugi szablon funkcji, której zadaniem będzie pobieranie wartości a.

template<typename typ>
void set_a(Test<typ> &t, int value)
{
	t.a = value;
}

template<typename typ>
int get_a(Test<typ> &t)
{
	return t.a;
}

Niestety składowa a jest zadeklarowana jako private i musimy nasze funkcje zaprzyjaźnić z szablonem Test. Robimy to w ten sposób:

template<typename typ>
class Test
{
template<typename typa>
friend void set_a(Test<typa> &t, int value);
template<typename typa>
friend int get_a(Test<typa> &t);
// tutaj reszta kodu...


A oto cały program:

#include <iostream>

using namespace std;

template<typename typ>
class Test
{
template<typename typa>
friend void set_a(Test<typa> &t, int value);
template<typename typa>
friend int get_a(Test<typa> &t);
private:
	int a;
	typ b;
public:
	Test() { a = 10; }
};

template<typename typ>
void set_a(Test<typ> &t, int value)
{
	t.a = value;
}

template<typename typ>
int get_a(Test<typ> &t)
{
	return t.a;
}


int main(int argc, char *argv[])
{
   Test<int> t;
   set_a(t, 5);
   cout<<"Test::a: "<<get_a(t)<<endl;
   return 0;
}


Problemy występują przypadku szablonów funkcji umieszczonych wewnątrz przestrzeni nazw. Np.:

namespace test
{
 template<typename T>
 void set(T &t)
 {
   t.a = 1;
 }
};

Wówczas poprawną składnią jest:

#include <iostream>

using namespace std;

template<typename t> class Test;

namespace test
{
  template<typename typ>
  void set_a(Test<typ> &t, int value)
  {
 	  t.a = value;
  }
}


template<typename typ>
class Test
{
      template<typename typa>
		  friend void test::set_a(Test<typa> &t, int value);

private:
	int a;
	typ b;
public:
	Test() { a = 10; }
};




int main(int argc, char *argv[])
{
   Test<int> t;
   test::set_a(t, 5);
   //cout<<"Test::a: "<<get_a(t)<<endl;
   return 0;
}

lub

class Test
{
 friend void test::set<Test>(Test &t);

Niestety nie wszystkie kompilatory akceptują poprawną składnię. Problemy ma między innymi gcc(wersje 3.3.3 i 3.3.1).

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

Więcej z Fandomu

Losowa wiki