C++ 扩展初始化列表
C++ extending initialization list
我希望能够使用通用外部函数以 'human readable' 形式显示不同的子classes。在每个实例中打印 'data' 是微不足道的,但我正在努力寻找一种优雅的方式来打印每个对象内容的详细信息(元)。
我可以通过以下 AsData
、FieldNames
和 GetFieldNames
的三元组来实现我想要的。 AsData
以可读形式打包成员数据,FieldNames
存储层次结构中那个点 class 的数据字段名称的静态列表,GetFieldNames
包装 FieldNames
具有可继承的功能:
class A {
public:
A(const string& name) { /* Setup data */ }
// ... functions to access data members go here ...
virtual const vector<string>& GetFieldNames() {
return A::FieldNames;
}
protected:
static const vector<string> FieldNames;
// ... some data members ...
};
class B : public A {
public:
B(const string& name, const string& description): A (name) { /* Setup extended data */ }
// ... functions to access additional data members go here ...
virtual const vector<string>& GetFieldNames() {
return B::FieldNames;
}
protected:
static const vector<string> FieldNames;
// ... some additional data members ...
};
所以用法可以如下:
void PrintTable (vector<shared_ptr<A> >& objects) {
// Print the field names.
for(const string& name : objects.front()->GetFieldNames())
cout << name << "\t";
// ... code to print the actual data goes here ...
}
int main(int argc, char **argv) {
vector<shared_ptr<A> > myObjects;
myObjects.push_back(make_shared<B>("Box", "Storage container"));
myObjects.push_back(make_shared<B>("Glass", "Drink container"));
PrintTable (myObjects);
return 0;
}
我想问一下是否可以重写静态常量成员并扩展它(我知道这听起来很矛盾),这样我就可以将字段添加到静态常量字段名称中,例如:
const vector<string> A::FieldNames = {"NAME"};
const vector<string> B::FieldNames = ClassA::FieldNames + {"DESC"}; // Obviously not possible!
我也很乐意使用 static const char* const FieldsConst[]
而不是 vector<string>
。
我看过 this answer and CRTP 但我认为它们不符合我的问题?
TIA :)
好的,我找到了一种方法——可以用 lamda 来完成。线索在 this question.
要按照我的意愿初始化 B::FieldNames
,我应该使用:
const vector<string> B::FieldNames = []
{ vector<string> v = A::FieldNames;
v.push_back("DESC");
return v; } ();
我希望能够使用通用外部函数以 'human readable' 形式显示不同的子classes。在每个实例中打印 'data' 是微不足道的,但我正在努力寻找一种优雅的方式来打印每个对象内容的详细信息(元)。
我可以通过以下 AsData
、FieldNames
和 GetFieldNames
的三元组来实现我想要的。 AsData
以可读形式打包成员数据,FieldNames
存储层次结构中那个点 class 的数据字段名称的静态列表,GetFieldNames
包装 FieldNames
具有可继承的功能:
class A {
public:
A(const string& name) { /* Setup data */ }
// ... functions to access data members go here ...
virtual const vector<string>& GetFieldNames() {
return A::FieldNames;
}
protected:
static const vector<string> FieldNames;
// ... some data members ...
};
class B : public A {
public:
B(const string& name, const string& description): A (name) { /* Setup extended data */ }
// ... functions to access additional data members go here ...
virtual const vector<string>& GetFieldNames() {
return B::FieldNames;
}
protected:
static const vector<string> FieldNames;
// ... some additional data members ...
};
所以用法可以如下:
void PrintTable (vector<shared_ptr<A> >& objects) {
// Print the field names.
for(const string& name : objects.front()->GetFieldNames())
cout << name << "\t";
// ... code to print the actual data goes here ...
}
int main(int argc, char **argv) {
vector<shared_ptr<A> > myObjects;
myObjects.push_back(make_shared<B>("Box", "Storage container"));
myObjects.push_back(make_shared<B>("Glass", "Drink container"));
PrintTable (myObjects);
return 0;
}
我想问一下是否可以重写静态常量成员并扩展它(我知道这听起来很矛盾),这样我就可以将字段添加到静态常量字段名称中,例如:
const vector<string> A::FieldNames = {"NAME"};
const vector<string> B::FieldNames = ClassA::FieldNames + {"DESC"}; // Obviously not possible!
我也很乐意使用 static const char* const FieldsConst[]
而不是 vector<string>
。
我看过 this answer and CRTP 但我认为它们不符合我的问题?
TIA :)
好的,我找到了一种方法——可以用 lamda 来完成。线索在 this question.
要按照我的意愿初始化 B::FieldNames
,我应该使用:
const vector<string> B::FieldNames = []
{ vector<string> v = A::FieldNames;
v.push_back("DESC");
return v; } ();