首页 > 解决方案 > 成员声明中的模板类类型别名替换失败

问题描述

假设您有一个class这样的模板:

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

put(...)并且您像这样在其中声明了一个方法。您如何在 ?put(...)之外声明该方法class

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

    /* 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])
    
  2. 这是另一种声明该put(...)方法使其工作的方法:

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

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

如何让第一个定义起作用,以便class在其声明和定义中保持对 ' 的特性(如类型别名)的使用一致,或者第二个定义是这里唯一的解决方案?

标签: c++classtemplatesaliasdeclaration

解决方案


如何让第一个定义起作用,以便在其声明和定义中保持对类特性(如类型别名)的使用一致,

我不得不承认我不理解错误,也不知道如何仅通过更改定义来修复它。错误消息相当混乱(您应该将其包含在问题中)。

...或者第二个定义是这里唯一的解决方案?

不它不是。如果您对length_t没有会员身份感到满意,那么这可能会为您指明正确的方向:

template <template<typename> typename T>
struct length { using type = int; };

template <template<typename> typename T>
using length_t = typename length<T>::type;


template <typename> struct Object;
template <> struct length<Object> { using type = unsigned int; };

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

template <typename type>
template <length_t<Object> length>
void Object<type>::put(type (&)[length]) {}

length是一个“模板特征”(不确定这个术语是否真的存在)。而不是length_t作为您的成员,Object您需要为length<Object>(并且需要前向声明Object)提供专业化。基本int情况仅用于说明。如果您愿意,您仍然可以将成员添加Object到 alias length_t<Object>

现场演示


推荐阅读