我有一个采用模板类型参数(tTRAIT)的类。我想和tTRAIT的模板类型成员别名成为 friend ,但是我无法弄清楚语法。 (这甚至可能吗?)。

template <bool bBOOL>
struct SFoo {};

struct STrait
    {
        template <bool bBOOL>
        using TFoo = SFoo<bBOOL>;
    };

template <typename tTRAIT>
struct SBar
    {
        template <bool bBOOL>
        friend typename tTRAIT::template TFoo<bBOOL>;
    };

SBar<STrait> bar;

Clang的错误(在friend行上)是:
error: friend type templates must use an elaborated type

我已经尝试了所有可能想到的组合:
friend tTRAIT::TFoo;
friend tTRAIT::template TFoo;
friend typename tTRAIT::TFoo;
friend typename tTRAIT::template TFoo;
template <bool bBOOL> friend tTRAIT::TFoo;
template <bool bBOOL> friend tTRAIT::TFoo<bBOOL>;
template <bool bBOOL> friend tTRAIT::template TFoo;
template <bool bBOOL> friend tTRAIT::template TFoo<bBOOL>;
template <bool bBOOL> friend typename tTRAIT::TFoo;
template <bool bBOOL> friend typename tTRAIT::TFoo<bBOOL>;
template <bool bBOOL> friend typename tTRAIT::template TFoo;
template <bool bBOOL> friend typename tTRAIT::template TFoo<bBOOL>;

我也尝试过使用using,但这似乎没有帮助。

作为一个丑陋的技巧(仅适用于 bool 参数),我可以通过手动将每个特化设置为好友来使其工作。
friend typename tTRAIT::template TFoo<false>;
friend typename tTRAIT::template TFoo<true >;

但这真令人讨厌。

有谁知道该怎么做,或者是否可以做到这一点?

最佳答案

我认为这是不可能的。根据标准草案N4296:

§14.5.4/1 [temp.friend]



这不包括别名模板,因此该标准不支持您要执行的操作。这可能是由于以下摘录(重点是我的):

§14.5.7/1 [temp.alias]



别名模板命名了一个单独的类型系列,因此,即使有一些对此有意义的语法,您也应该将别名模板而不是被别名的模板作为 friend 。

例如,GCC将编译此代码(Clang不会),但实际上您将无法以任何合理的方式使用友谊:

template <bool B>
using MyTFoo = typename tTRAIT::template TFoo<B>;

template <bool> friend class MyTFoo;

别名模板与别名模板不同的另一个示例:
template <template <typename...> class A, template <typename...> class B>
struct is_same_template : std::false_type{};

template <template <typename...> class A>
struct is_same_template<A,A> : std::true_type{};

template <typename T> using myvec = std::vector<T>;

//this fails
static_assert(is_same_template<myvec,std::vector>::value, "wat");

您可以手动使用显式实例化,因为别名模板将折叠为与别名模板完全相同的类型。一个类似的例子:
//this passes!
static_assert(std::is_same<myvec<int>,std::vector<int>>::value, "wat");

07-24 09:45
查看更多