I've got a class template with a template template parameter, and I want to declare this parameter (that is, all of its specializations) as a friend
. But I can't find the correct syntax.
template <template <class> class T>
struct Foo {
template <class U>
friend T; // "C++ requires a type specifier for all declarations"
template <class U>
friend struct T; // "declaration of 'T' shadows template parameter"
template <class U>
friend struct T<U>; // "cannot specialize a template template parameter"
pretty<please>
lets(be) friends T; // Compiler shook its standard output in pity
};
How can I declare a template template parameter as friend
?
Coliru snippet
Templates can be template parameters. In this case, they are called template parameters. The container adaptors std::stack, std::queue, and std::priority_queue use per default a std::deque to hold their arguments, but you can use a different container.
A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)
Why we use :: template-template parameter? Explanation: It is used to adapt a policy into binary ones.
One-to-one: A template function instantiated with one set of template arguments may be a friend to one template class instantiated with the same set of template arguments. This is also the relationship between a regular non-template class and a regular non-template friend function.
I've found this problem is very interesting to research. According to standard (C++11 and above) this should works fine, I guess:
template <template <class> class U>
struct identity {
template <typename T>
using type = U<T>;
};
template <template <class> class U>
struct Foo {
template <typename>
friend class identity<U>::type;
};
Due to one indirection level, there are no any shadowing and name reusing here, and this situation described as following:
cppreference:
Both function template and class template declarations may appear with the friend specifier in any non-local class or class template (...). In this case, every specialization of the template becomes a friend, whether it is implicitly instantiated, partially specialized, or explicitly specialized. Example:
class A { template<typename> friend class B; }
However, it seems like clang and MSVC think otherwise: see coliru or godbolt. Moreover, their error messages seem meaningless, so it looks like a compiler bug (or just an incorrectly detected syntax error). GCC compiles and executes mentioned snippets perfectly, but I still not sure it's a correct solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With