如何使这个带有可变参数的模板专业化成为 class 的朋友?

How do I make this template specialization with variadic arguments a friend of a class?

我有以下生成器函数:

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)...));
}

我想让它成为唯一可以创建以下实例的东西 class,所以我将 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'

我已经尝试了一些看起来合理的变体,但我不确定此处将模板特化声明为友元的正确语法是什么。

这个声明有两个问题:

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;

没有 "conditional friendship" 这样的概念可以让你只与 Bar 成为朋友(例如,你不能在此处添加限制以仅限制 Bar)。