前言
下面有一个 SSCCE 链接。
我已经定义了一个模板类,它在我的程序中声明了一个嵌套类。std::ostream::operator <<
该模板适用于许多不同的数据类型(即被std::ostream::operator <<
.
所以这是基本界面:
class Value;
class Datatype {
public:
virtual std::string to_string(Value* value) = 0;
};
class Value {
Datatype* m_type;
public:
Value(Datatype* type) : m_type(type) { }
std::string to_string() {
return m_type->to_string(this);
}
};
模板类的WrapValueImpl
作用(见下文)是将一个Value
和Datatype
实现合二为一。
template <typename T>
class WrapValueImpl : public Value {
T m_val;
public:
WrapValueImpl(Datatype* type) : Value(type) { }
T& get() {
return m_val;
}
static T& get(Value* value) {
return static_cast<WrapValueImpl*>(value)->get();
}
static void set(Value* value, const T& other) {
get(value) = other;
}
class Type : public ::Datatype {
public:
virtual std::string to_string(Value* value) {
std::ostringstream stream;
stream << WrapValueImpl::get(value);
return stream.str();
}
};
};
示例用法:
typedef WrapValueImpl<int> IntValue;
int main() {
IntValue::Type t;
IntValue v(&t);
IntValue::set(&v, 42);
std::cout << v.to_string() << "\n"; // prints 42
return 0;
}
到目前为止一切顺利,这正是我想要的。
问题
但是现在,我想WrapValueImpl
使用std::ostream::operator <<
. 请再次注意,我不想添加对<<
运营商的支持。
更确切地说,我想覆盖 中的Type
类WrapValueImpl
以实现正确的字符串转换。
typedef std::vector<Value*> ValueArray;
class ArrayValue : public WrapValueImpl<ValueArray> {
public:
ArrayValue(Datatype* type) : WrapValueImpl<ValueArray>(type) { }
class Type : public WrapValueImpl<ValueArray>::Type {
public:
virtual std::string to_string(Value* value) {
std::ostringstream stream;
stream << "[";
ValueArray& array = ArrayValue::get(value);
ValueArray::const_iterator it = array.begin();
for (; it != array.end(); it++) {
stream << (*it)->to_string() << ", ";
}
stream << "]";
return stream.str();
}
};
};
但它根本不编译。编译器会产生错误,就好像我使用的是原始WrapValueImpl<ValueArray>::Type
类而不是ArrayValue::Type
类一样。但是,我确实进行了测试并插入了打印件,Type::to_string()
并调用了正确的方法(被覆盖类的方法)。
(SSCCE)但它实际上使用了正确的Type
类......
在以下关于 Coliru 的片段中,您可以找到我正在谈论的完整工作示例。您可以切换USE_ARRAY
宏来查看使用ArrayValue
类的结果。
http://coliru.stacked-crooked.com/a/820e2f2550a8363e
在这个例子中,我还证明了编译器实际上选择了正确的嵌套类型类,但它抱怨原始实现。为什么它实际上不使用 type时会打扰?