C:修改模板类型成员模板参数的正确语法?

我有一个类接受模板类型参数(tTRAIT).我想要朋友一个模板类型的成员别名的tTRAIT,但我无法弄清楚语法. (这甚至可能吗?).

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的错误(在朋友行上)是:

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

我也试过使用,但似乎没有帮助.

作为一个丑陋的黑客(仅适用于布尔参数),我可以通过手动修改每个专业化来使其工作.

friend typename tTRAIT::template TFoo<false>;
friend typename tTRAIT::template TFoo<true >;

但是这很幸运

有谁知道如何做到这一点,还是可以做到这一点?

最佳答案
我不认为这是可能的.从标准草案N4296:

§14.5.4 / 1 [temp.friend]

A friend of a class or class template can be a function template or class template, a specialization of a
function template or class template, or a non-template function or class.

这不包括别名模板,因此该标准不支持您想要做的.这可能是由于以下摘录(强调我的):

§14.5.7 / 1 [temp.alias]

A template-declaration in which the declaration is an alias-declaration (Clause 7) declares the identifier to
be a alias template. An alias template is a name for a family of types.

一个别名模板命名一个单独的类型的系列,所以即使有一些语法对此有意义,您将是修补别名模板,而不是被别名的模板.

例如,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");

转载注明原文:C:修改模板类型成员模板参数的正确语法? - 代码日志