结交模板模板参数

时间:2017-03-16 23:20:41

标签: c++ templates friend template-templates

我有一个带有模板模板参数的类模板,我想将此参数(即其所有特化)声明为friend。但我无法找到正确的语法。

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

如何将模板模板参数声明为friend

Coliru snippet

2 个答案:

答案 0 :(得分:1)

我发现这个问题对研究很有意思。根据标准(C ++ 11及以上版本),这应该可行,我猜:

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

由于一个间接级别,此处没有任何阴影和名称重用,这种情况描述如下:

  

cppreference

     

函数模板和类模板声明都可以与任何非本地类或类模板(...)中的友元说明符一起出现。在这种情况下,模板的每个特化都成为朋友,无论是隐式实例化,部分专用还是显式专用。示例:class A { template<typename> friend class B; }

然而,似乎clang和MSVC不这么认为:见colirugodbolt。此外,它们的错误消息似乎毫无意义,因此它看起来像编译器错误(或只是错误检测到的语法错误)。 GCC完美地编译和执行提到的片段,但我仍然不确定它是否是正确的解决方案。

答案 1 :(得分:-1)

模板往往会让程序员过度复杂化。我不确定你要做什么,我怀疑可能有更好的方法,但这应该有效。

template <template <class> class T, class U>
class Foo {
    friend class T<U>;
};