Как сделать эту специализацию шаблона с аргументами variadi c другом класса? - PullRequest
1 голос
/ 08 апреля 2020

У меня есть следующая функция компоновщика:

template <typename T>
struct Wrapper {
    Wrapper(T);
};

template <typename T, typename... Args>
inline Wrapper<T>
buildWrapper(Args&&... args) noexcept { 
  return Wrapper<T>(T(std::forward<Args>(args)...));
}

Я хочу сделать это единственным, что может создать экземпляр следующего класса, поэтому я сделал ctor закрытым и попытался пометить Приведенный выше шаблон работает как друг.

class Bar {
private:
  Bar(bool);
  friend inline Wrapper<Bar> buildWrapper<Bar>(bool) noexcept;
}

Но это приводит к ошибке:

error: no function template matches function template specialization 'buildWrapper'
note: candidate template ignored: could not match 'type-parameter-0-1 &&' against 'bool'

Я пробовал некоторые разумно выглядящие варианты, но я просто не уверен, что правильно Синтаксис здесь, чтобы объявить специализацию шаблона как друга.

1 Ответ

3 голосов
/ 08 апреля 2020

Есть две проблемы с этим объявлением:

friend inline Wrapper<Bar> buildWrapper<Bar>(bool) noexcept;
  1. Вы не можете использовать спецификатор inline здесь.
  2. Нет такой специализации buildWrapper это принимает bool аргумент. Ваш шаблон функции принимает ссылки для пересылки, поэтому он всегда будет ссылаться на bool.

Правильное написание:

friend Wrapper<Bar> buildWrapper<Bar>(bool&&) noexcept;

Хотя тогда вам, вероятно, придется дополнительно подружиться с другими видами bool параметров, что быстро становится громоздким. Проще просто подружиться со всеми из них:

template <typename T, typename... Args>
friend Wrapper<T> buildWrapper(Args&&...) noexcept;

Нет такого понятия "условной дружбы", которое позволило бы вам просто подружиться с Bar (например, вы не можете добавить здесь ограничения, чтобы просто ограничить к Bar с).

...