使用模板依赖类型

时间:2015-08-05 17:49:32

标签: c++ templates

我正在尝试使用模板对类中的字段进行编码 - 我正在研究有线协议 - 但这些模板让我很难过。基本上,我希望能够使用模板指定“字段”以及如何为电线编码(除此之外,我正在简化此问题)。这是我的尝试,但是我得到了一个编译时错误(见下文) - 这是我对依赖类型名称没有正确做的事情吗?

// Encodes values, but identity for this example
template <typename T>
struct Encoder {
  typename T::type operator()(const typename T::type& value) {
    return value;
  }
};

// Declares the properties of Fields (such as Encoding...)
template <typename T, typename E=Encoder<T>>
struct Field {
  typedef T type;
  typedef E encoder;
};

// A root for all classes that need Encoded Fields
struct C {
  template <typename T>
  void set(const typename T::type& value) {
    typename T::encoder encode;
    encode(value);
  }
};

// A mock specific class with 1 Encoded Field
struct H : C {
  typedef Field<int> my_field;
};

int main() {
  H h;
  h.set<H::my_field>(3);
}

编译错误是:

 In instantiation of 'struct Encoder<int>': 
   required from 'void C::set(const typename T::type&) [ with T = F<int>; typename T::type = int]'
   required from here
 error: 'int' is not a class, struct or union type
 typename T::type operator()(const typename T::type& value) {

2 个答案:

答案 0 :(得分:3)

作为实例化过程的一部分,您创建Encoder<int>。但是Encoder<T>有一个成员函数:

typename T::type operator()(const typename T::type& value);

你无法评估int::type。但基于C::set()

template <typename T>                        // T = Field<int>
void set(const typename T::type& value) {    // value is int
    typename T::encoder encode;              // encode is Encoder<int>
    encode(value);        
}

您只是直接传递了值,因此相关的value只是T。也就是说,您的Encoder应为:

template <typename T>
struct Encoder {
  T operator()(const T& value) {
    return value;
  }
};

这也使语义更具意义。 Encoder需要T并返回其他T。通过该更改,您的代码将进行编译。

答案 1 :(得分:2)

  

这是我对依赖类型名称没有正确做的事情吗?

用于实例化Encoder的类型为int,而不是Field<int>

Encoder更改为:

template <typename T>
struct Encoder {
  T operator()(const T& value) {
    return value;
  }
};

有效,但我不确定你是否有其他想法。