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