LINUX.ORG.RU

[крабокрабр] Придумались френды для плюсовых темплейтов


0

2

Хей. Поскольку бложиков не имею (задрали), а забавная штучка придумалась, оставлю тут, вдруг кому пригодится.

class Wrapper
{
protected:
  struct FriendlyCall {};
};

class FriendshipReceiver
  : private Wrapper
{
public:
  void test1(const FriendlyCall& fc)
  {

  }
  template<typename X>
  void test2(const FriendlyCall& fc = X())
  {

  }
};

class FriendshipCaller
  : private Wrapper
{
public:
  void test()
  {
    FriendshipReceiver r;
    r.test1(FriendlyCall()); // ok
    r.test2<FriendlyCall>(); // ok
  }
};

class BadCaller
{
public:
  void test()
  {
    FriendshipReceiver r;
    //r.test1(FriendlyCall());
    //r.test2<int>(); // fail
    //r.test2(); // fail
  }
}; 

Примечание: здесь FriendshipCaller/FrienshipReceiver могут быть темплейтными, а для них нельзя делать friend class ...; По сути, здесь test*() - протектнутые функции, которые позволено вызывать снаружи некоторым избранным классам.



Последнее исправление: wolfy (всего исправлений: 3)

Не совсем понял, а если test1 и test2 просто объявить как protected, то нужный эффект не получим?

static_lab ★★★★★
()
Ответ на: комментарий от Zhbert

Это эмуляция семантики отношения дружественности для шаблонных классов, где она не работает. Здесь FriendshipCaller/FrienshipReceiver могут быть темплейтными, а для них нельзя делать friend class ...;

wolfy
() автор топика
Ответ на: комментарий от wolfy

По сути, здесь test*() - протектнутые функции, которые позволено вызывать снаружи некоторым избранным классам.

wolfy
() автор топика
Ответ на: комментарий от wolfy

> По сути, здесь test*() - протектнутые функции, которые позволено вызывать снаружи некоторым избранным классам.

Вероятно, я не постиг всю идею. И мне кажется, что избранным окажется любой класс, отнаследовавшийся от Wrapper. В то время как обычный friend пишется в определении класса и сразу видно, кто именно друзья.

const86 ★★★★★
()
Ответ на: комментарий от const86

Ну так и есть, да, но тут уж ничего не поделаешь. Эмуляция - она и есть эмуляция, жизнь жестока, это необычный френд.

Хотя если речь идет только о «посмотреть список френдов», то find references или банальный греп спасают.

А вообще сия игра разума полезна при создании навороченных метапрограмм.

wolfy
() автор топика
Ответ на: комментарий от wolfy

для них нельзя делать friend

template<typename T>
class Test
{
	template<class T2>
	friend class Test2;
private:
	void foo()
	{
	}
};

template<typename T>
class Test2
{
public:
	void bar()
	{
		Test<int> t;
		t.foo();
	}
};

int main()
{
	Test2<int> t;
	t.bar();
}

ЧЯДН?

Booster ★★
()
Ответ на: комментарий от wolfy

VS 2005 тоже кушает нормально. Видимо у вас совсем что-то древнее.

Booster ★★
()
Ответ на: комментарий от wolfy

По поводу вашей ссылки, то по моему там бред. Непонятно зачем такое делать.

Booster ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.