简体   繁体   中英

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

I have the following builder function:

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

I want to make this the only thing that can create an instance of the following class, so I've made the ctor private and attempted to mark the above template function as a friend.

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

But this generates an error:

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

I've tried some reasonable looking variations, but I'm just not sure what the correct syntax here to declare the template specialization as a friend.

There are two problems with this declaration:

friend inline Wrapper<Bar> buildWrapper<Bar>(bool) noexcept;
  1. You can't use the inline specifier here.
  2. There is no such specialization of buildWrapper that takes a bool argument. Your function template takes forwarding references, so it would always take some kind of reference to bool .

The correct spelling is:

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

Although you probably would then have to additionally friend the other kinds of bool parameters, which gets unwieldy quickly. Easier to just friend all of 'em:

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

There's no such concept of "conditional friendship" that would let you just friend the Bar ones (eg you can't add constraints here to just limit to the Bar s).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM