В чем смысл синтаксиса, выбранного для объявления друзей по шаблону? - PullRequest
9 голосов
/ 24 июля 2011

Объявление друзей в функции шаблона включает в себя невероятно неинтуитивный синтаксис, даже для C ++! Каково обоснование выбора синтаксиса для необходимого дополнительного <>? Разве не имеет смысла использовать ключевое слово template?

Для тех, кто не знает об этом, вот пример того, что вы можете попытаться сделать:

template <typename T>
class Foo
{
  int x;
  friend void bar(Foo<T>);
};

template <typename T>
void bar(Foo<T> f)
{
  std::cout << f.x;
}

Если вы попытаетесь позвонить bar(Foo<T>()), вы получите ошибки компоновщика.

Чтобы решить эту проблему, вы должны переслать объявление bar (и, следовательно, Foo), а затем вставить странное место <> в объявление друга.

template <typename T> class Foo;
template <typename T> void bar(Foo<T>);

template <typename T>
class Foo
{
  int x;
  friend void bar<>(Foo<T>); // note the <> (!?)
};

template <typename T>
void bar(Foo<T> f)
{
    std::cout << f.x;
}

Мой вопрос: в чем смысл синтаксиса <>? Разве не было бы более интуитивно понятно использовать ключевое слово template или что-то в этом роде?

РЕДАКТИРОВАТЬ: Чтобы уточнить, Я уже знаю , почему требуется <>, я хочу знать, почему они решили использовать <> для устранения неоднозначности, вместо некоторого другого более интуитивного синтаксиса .

Ответы [ 2 ]

6 голосов
/ 24 июля 2011

Подождите. Вы не объявите друга шаблоном. Вы объявляете специализацию шаблона как друга! Как таковой, почему вы хотите поместить туда предложение template?

Синтаксис для имен специализаций шаблонов функций - teplateName<ArgumentList>, и это то, что вы должны использовать в соответствии со Стандартом в декларациях друзей.

Если вы хотите подружиться со всем шаблоном и всеми специализациями, сгенерированными и явно специализированными, вы все равно можете это сделать, и тогда вы можете использовать предложение шаблона

template<typename U>
friend void bar(Foo<U>);
2 голосов
/ 24 июля 2011

Цитирование эта страница :

Не шаблонная функция вызывается, потому что не шаблонная функция имеет приоритет в разрешении перегрузки.

Так что я думаю, friend void bar<>(Foo<T>); интуитивно понятен, потому что вы хотите убедиться, что вызываете функцию шаблона, а не перегрузку для Foo<T>. В противном случае компилятор не мог бы заметить, является ли шаблонная или не шаблонная функция другом класса.

Почему используется синтаксис <>, а не синтаксис template, мне неясно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...