实体的成员类型为std :: array。 Student继承自Entity,需要初始化它继承的std :: array成员var。下面是我用来执行此操作的代码,但它涉及将括号括起的列表转换为std :: array。我不确定这是正确或最佳的方法。使用括号括起或双括号括起的列表而不进行强制转换会导致编译错误。我已经尝试了几种初始化std :: array成员var的方法没有成功,所以我似乎陷入了我当前的方法。有更好的方法吗?:
template<typename... Args> struct Entity {
typedef const char* name_t;
typedef const array<const char*, sizeof...(Args)> source_names_t;
const tuple<Args...> data;
name_t name;
//This will be initialized by derived class Student.
source_names_t source_names;
Entity(
name_t tmp_name
, source_names_t tmp_source_names
)
: name(tmp_name)
, source_names(tmp_source_names)
{}
};
//idnum, fname, lname, married
struct Student : Entity<int, string, string, bool> {
Student()
: Student::Entity(
"student"
//Now Student initializes the array, but does it by casting.
, (source_names_t) {{"id", "lname", "fname", "married"}}
)
{}
};
答案 0 :(得分:1)
有两个选项,但其中一个依赖于运行时大小验证。请注意,我的示例中的后者等同于强制转换。铸造有什么问题?
#include <cassert>
#include <algorithm>
#include <array>
#include <initializer_list>
#include <iostream>
struct A {
typedef std::array<char const*, 3> T;
T data_;
A(std::initializer_list<char const*> const& data) {
assert(data.size() <= data_.size()); // or ==
// of course, use different error handling as appropriate
std::copy(data.begin(), data.end(), data_.begin());
std::fill(data_.begin() + data.size(), data_.end(), nullptr);
}
A(T const& data) : data_ (data) {}
};
int main() {
A a ({"a", "b"});
std::cout << (void const*)a.data_[2] << '\n';
A b ((A::T{"a", "b"})); // might just be the compiler I tested, but the
// extra parens were required; could be related
// to "the most vexing parse" problem
std::cout << (void const*)b.data_[2] << '\n';
return 0;
}
但是,对于每个Student对象,此数据看起来都是相同的。为什么不使用虚方法或将共享对象传递给基本ctor?您可以复制该对象,下面的 entity_data _ - 这相当于您当前的代码 - 或者要求它超过并存储指针/引用。
struct Student : Entity<int, string, string, bool> {
Student() : Entity<int, string, string, bool>("student", entity_data_) {}
// the template arguments are still required in 0x, I believe
private:
static Entity<int, string, string, bool>::source_names_t entity_data_;
}