模板类类型别名在成员声明中替换失败 [英] Template class type alias failing substitution in member declaration

查看:58
本文介绍了模板类类型别名在成员声明中替换失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您有一个模板化的 class ,如下所示:

Assume you have a templated class like this:

template <typename type>
class Object {
  using length_t = unsigned int;
  
  template <length_t length>
  void put(type (&)[length]);
};

,您在其中声明了一个 put(...)方法,如下所示.您如何去声明 class 之外的 put(...)方法?

and you declared a put(...) method in it like so. How do you go about declaring that put(...) method outside the class?

  1. 这是某人可能采取的一种方法:

  1. Here's one approach someone might take:

/* ERROR: Doesn't match any declarations(?) */
template <typename type>
template <typename Object<type>::length_t length>
void Object<type>::put(type (&)[length]) {}

但这会导致特殊的错误

error: no declaration matches 'void Object<type>::put(type (&)[length])'

note: candidate is: 
  template <class type>
  template <unsigned int length>
  void Object<type>::put(type (&)[length])

  • 这是另一种声明 put(...)方法以使其起作用的方法:

  • Here's another way to declare the put(...) method such that it works:

    /* SUCCESS: But `length_t` alias isn't used */
    template <typename type>
    template <unsigned int length>
    void Object<type>::put(type (&)[length]) {}
    

    ,但未使用 class 中定义的 length_t 类型别名.

    but the length_t type alias defined in the class isn't used.

    如何使第一个定义起作用,以便在其声明&中保持 class 的功能(例如类型别名)的一致性.定义,还是第二个定义是这里唯一的解决方案?

    How does one get the first definition to work so as to keep the use of the class's features (like type aliases) consistent across its declaration & definitions, or is the second definition the only solution here?

    推荐答案

    我认为这是编译器错误,或更严重的是标准缺陷.

    I think it's a compiler bug, or further more, a defect in standard.

    您的代码实际上没有问题,并且被 MSVC 接受.如果将定义放在类中,则没有编译器会认为它格式错误.

    your code actually has NO problem, and is accepted by MSVC. and if you put the definition inside the class, no compiler will think it's ill-formed.

    我发布了问题与此类似.我得到的结果是 CWG2 ,这是一个没人知道的古老问题,它仍在起草中,这意味着超出范围的匹配规则甚至未指定.这些奇怪的不匹配是由于编译器的实现方式不同.

    I have posted a question that is similar to this. and I get the result that, CWG2, the ancient issue that nobody knows when it's posted, is still drafting, which means the match rule of out-of-definition is even unspecified. these weird mismatches are because of the different implementations of compilers.

    然后,为了避免这个问题,首先可以将定义放入类中.并且如果它依赖于在类定义后面定义的东西并且不能在内部定义,则可以:

    and then, for how to avoid this problem, firstly you can put the definition inside the class. and if it depends on something defined behind the class definition and can not be defined inside, you can:

    1. 使其独立:在外部使用 length_t = unsigned int; .
    2. 在声明时使其可推论:编译器可能不知道 typename Object< type> :: length_t length_t (在类内部)尽管不需要推导 typename Object< type> :: length_t ,但是它们是相同的类型.因为在声明的那一刻,在我看来,编译器无法确保是否指定了 Object< type> ,并使 length_t 不匹配.就像@idclev 463035818所说的那样, template< ...>使用length_t = unsigned int; 将使编译器更容易匹配此定义.
    1. make it independent: let using length_t = unsigned int; outside.
    2. make it deducible when declaring: compilers may not know if typename Object<type>::length_t and length_t (inside the class) are the same type, although typename Object<type>::length_t is not needed to be deducible. because at the declaring moment, compiler can not ensure if Object<type> is specified and make length_t mismatched, in my mind. so as what @idclev 463035818 said, template<...> using length_t = unsigned int; will make compiler easier to match this definition.

    这篇关于模板类类型别名在成员声明中替换失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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