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;
inline
specifier here.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 (e.g. you can't add constraints here to just limit to the Bar
s).