C ++:更正模板参数的模板类型成员的语法? [英] C++: Correct syntax for friending a template type member of template parameter?

查看:159
本文介绍了C ++:更正模板参数的模板类型成员的语法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类,它接受一个模板类型参数(tTRAIT)。我想要朋友一个tTRAIT的模板类型 别名,但我不知道语法。 (这是可能吗?)。

 模板< 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>酒吧;

Clang的错误(在 friend 行)是:

 错误:friend类型模板必须使用详细的类型

我试着用尽所有可能的组合:

  friend tTRAIT :: TFoo; 
friend tTRAIT :: template TFoo;
friend typename tTRAIT :: TFoo;
friend typename tTRAIT :: template TFoo;
template< bool bBOOL>朋友tTRAIT :: TFoo;
template< bool bBOOL> friend tTRAIT :: TFoo< bBOOL> ;;
template< bool bBOOL>朋友tTRAIT :: template TFoo;
template< bool bBOOL> friend tTRAIT :: template TFoo< bBOOL> ;;
template< bool bBOOL>朋友类型名tTRAIT :: TFoo;
template< bool bBOOL>朋友类型名称tTRAIT :: TFoo< bBOOL> ;;
template< bool bBOOL>朋友类型名tTRAIT :: template TFoo;
template< bool bBOOL>朋友类型名称tTRAIT :: template TFoo< bBOOL> ;;


我还尝试使用使用它似乎不帮助。



作为一个丑陋的黑客(它只适用于bool参数),我可以让它工作通过手工每个专业化。 p>

 朋友类型名称tTRAIT :: template TFoo< false> ;; 
friend typename tTRAIT :: template TFoo< true> ;;

但是很幸运。



知道如何做到这一点,或者如果可以这样做?

解决方案

我不认为这是可能的。从标准草稿N4296起:



§14.5.4 / 1 [temp.friend]


类或类模板的朋友可以是函数模板或类模板,
函数模板或类模板的特化,或非模板函数或类。


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



§14.5.7 / 1 [temp.alias]


其中声明是别名声明的模板声明(第7条)将
的标识符声明为别名模板。 别名模板是一系列类型的名称


别名模板命名一个单独的家庭类型,所以即使有一些语法对此有意义,你会喜欢别名模板,而不是别名模板。



例如,GCC将编译这个(Clang不会),但你实际上不能以任何合理的方式使用友谊:

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

template< bool> friend class MyTFoo;

另一个别名模板与别名模板不同的示例:

 模板< template< typename ...>类A,模板< typename ...> B类> 
struct is_same_template:std :: false_type {};

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

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

//这失败
static_assert(is_same_template< myvec,std :: vector> :: value,wat);

使用显式实例化的手动协商将有效,因为别名模板将崩溃到完全相同的类型作为别名模板。类似的示例:

  // this passed! 
static_assert(std :: is_same< myvec< int>,std :: vector< int>> :: value,wat);


I have a class that takes a template type parameter (tTRAIT). I want to friend a template type member alias of tTRAIT, but I can't figure out the syntax. (Is this even possible?).

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's error (on the friend line) is:

error: friend type templates must use an elaborated type

I have tried exhausting all possible combinations I can think of:

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

I have also tried using using, but it doesn't seem to help.

As an ugly hack (which only works for bool parameters), I can get it to work by friending each specialization manually.

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

But that's yucky.

Does anyone know how to do this, or if this can be done?

解决方案

I don't think this is possible. From standard draft 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.

This doesn't include alias templates, so the standard doesn't support what you want to do. This is perhaps due to the following excerpt (emphasis mine):

§ 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.

An alias template names a separate family of types, so even if there were some syntax which made sense for this, you would be friending the alias template rather than the template which is being aliased.

For example, GCC will compile this (Clang won't), but you won't actually be able to use the friendship in any reasonable way:

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

template <bool> friend class MyTFoo; 

Another example of how an alias template is not the same as the aliased template:

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

Your manual friending with explicit instantiation will work, because the alias template will collapse down to exactly the same type as the aliased template. An analogous example:

//this passes!
static_assert(std::is_same<myvec<int>,std::vector<int>>::value, "wat");

这篇关于C ++:更正模板参数的模板类型成员的语法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆