对类型相关的模板名称使用声明 [英] Using declaration for type-dependent template name

查看:101
本文介绍了对类型相关的模板名称使用声明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在模板内部使用CRTP时(或通常在将模板参数作为基类模板参数传递时),是否不可能在using声明中命名基类的成员模板?

When CRTP is used inside a template, (or generally when a template parameter is passed as a base class template argument), is it impossible to name the base's member templates in a using declaration?

template< typename d >
struct base {
    template< typename >
    struct ct {};

    template< typename >
    void ft() {}
};

template< typename x >
struct derived : base< derived< x > > {
     using derived::base::template ct; // doesn't work
     using derived::base::ft; // works but can't be used in a template-id
};

在我看来,这只是语言上的一个空洞,仅仅是因为 using-declaration 语法生成没有包含 qualified-id .

It seems to me that this is a hole in the language, simply because the using-declaration grammar production doesn't incorporate a qualified-id.

using-declaration:
    using typename(opt) nested-name-specifier unqualified-id ; // have this
    using :: unqualified-id ;

unqualified-id:
    identifier
    operator-function-id
    conversion-function-id
    literal-operator-id
    ~ class-name
    ~ decltype-specifier
    template-id

qualified-id:
    nested-name-specifier template(opt) unqualified-id // want this
    :: identifier
    :: operator-function-id
    :: literal-operator-id
    :: template-id

如果唯一的规则是using-declaration: using typename(opt) qualified-id,那么唯一的后果就是

If the only rule were using-declaration: using typename(opt) qualified-id, the only consequences would be

  • 排除没有语义意义的:: conversion-function-id:: ~ class-name:: ~ decltype-specifier template-id
  • 允许:: template-id已被7.3.3/5明确禁止,并且
  • 允许template关键字,该关键字已经具有足够的规范来修补该孔.
  • ruling out :: conversion-function-id, :: ~ class-name, and :: ~ decltype-specifier template-id which make no semantic sense,
  • allowing :: template-id which is already expressly forbidden by 7.3.3/5, and
  • allowing the template keyword which already has sufficient specification to patch the hole.

此分析正确吗?

鉴于允许使用新语法,也许使用typename的声明应导入类模板或别名模板,而没有typename的声明应将函数或变量模板导入当前范围.

Given that the new grammar were allowed, perhaps a declaration with typename should import a class template or alias template, and one without typename should import a function or variable template into the current scope.

     using typename derived::base::template ct;
     using derived::base::ft;

这可能需要一些其他规范.另外,当前的现状似乎是,依赖的模板名称总是具有不明确的种类(不是模板ID),因此尚不清楚typename完全属于ct.

This might require some additional specification. Also, the current status quo seems to be that dependent template-names always have ambiguous kind (not template-ids), so it's not clear that typename belongs with ct at all.

推荐答案

以下在C ++ 11上可以正常使用:

The following works fine with C++11:

#include <iostream>

template< typename d >
struct base {
    template< typename >
    struct ct {};

    template< typename >
    void ft() {std::cerr << "cheesecake" << std::endl;}
};

template< typename x >
struct derived : base< derived< x > > {
  template<typename X>
    using ct = typename derived::base::template ct<X>; // new in C++11
  using derived::base::ft;
};

int main()
{
  derived<int>::ct<float> c;
  derived<int> a;
  a.ft<int>();
}

如果这不是您想要的,请举例说明如何使用 ct ft ?

If that is not what you wanted, can you please give an example of how you would want to use ct and ft?

这篇关于对类型相关的模板名称使用声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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