C++ 与模板参数交朋友

C++ 与模板参数交朋友,c++,templates,friend,template-templates,C++,Templates,Friend,Template Templates,我有一个带有template template参数的类模板,我想将这个参数(即它的所有专门化)声明为一个朋友。但是我找不到正确的语法 template <template <class> class T> struct Foo { template <class U> friend T; // "C++ requires a type specifier for all declarations" templat

我有一个带有template template参数的类模板,我想将这个参数(即它的所有专门化)声明为一个
朋友
。但是我找不到正确的语法

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
};
模板
结构Foo{
模板
friend T;/“C++要求所有声明都使用类型说明符”
模板
friend struct T;//“T”阴影模板参数的声明”
模板
friend struct T;//“无法专门化模板参数”
漂亮的
lets(be)friends T;//编译器遗憾地摇了摇它的标准输出
};
如何将模板参数声明为
friend


模板往往会让程序员把事情复杂化。我不确定你想做什么,我怀疑可能有更好的方法,但这应该行得通

template <template <class> class T, class U>
class Foo {
    friend class T<U>;
};
模板
福班{
朋友级T;
};

我发现这个问题非常值得研究。根据标准(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;
};
模板
结构标识{
模板
使用类型=U;
};
模板
结构Foo{
模板
好友类标识::类型;
};
由于有一个间接层,这里没有任何阴影和名称重用,这种情况描述如下:

:

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


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

我没有答案,但这里有一些参考:-被认为不是缺陷,尽管我真的不知道其基本原理是什么意思。也,;GCC确实接受
模板友元类T,Clang和EDG会拒绝它(MSVC不会直接拒绝它,但它似乎也没有做什么有用的事情)。第三种形式是不允许的。我不确定你想表达什么,但这可能会起作用?
模板结构Foo{friend t;}
的确,我同意在当前的措辞下,这种形式是无效的(
T
是一种部分专门化,尽管它是无效的,因为它不比主要的更专门化)。我希望正确的形式要么是示例中的第一个,要么就是
friend T,如CWG585的建议解决方案中所述,以使其与非模板参数保持一致。从严格的标准来看,现在的情况似乎一团糟标准批准的语法。哇,这看起来非常奇怪——我不知道模板参数推断和朋友声明是如何相互作用的,但我很惊讶这在非推断的上下文中起作用+1尽管如此,这看起来像是有价值的信息:)