2010-09-03 87 views
0

实体具有std :: array类型的成员变量。学生从实体继承,并且需要初始化它继承的std :: array成员变量。下面是我用来做到这一点的代码,但它涉及将一个大括号括起来的列表转换为std :: array。我不确定这是做到这一点的正确或最佳方式。在没有转换的情况下使用大括号括号或双大括号括起来的列表会导致编译错误。我尝试了几种其他的方式来初始化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

作为一个风格的笔记,我不认为'decltype'是一些有名的'typedef'的好替代品。 – 2010-09-03 19:17:26

+0

我看到我可以使用typedef作为名称成员,但我是否也可以为source_names做到这一点?感谢您的建议。总是可以使用更多提示。 – 2010-09-03 19:20:00

+0

'typedef array source_names_type;' – 2010-09-03 19:22:30

回答

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_; 
} 
+0

铸造有什么问题?呃......我猜想什么都没有,我只是不知道我是否错过了一些重要的东西,或者是否有更好的方法。对我来说,我不得不将一个支撑列表强制转换为一个std :: array对象,以便在初始化列表中进行初始化。这样做与原始数组我认为会很好,但这是我第一次搞乱W/STD ::数组与原始数组。不太确定要避免什么。不管怎样,谢谢。如果在我绘制的场景中没有人看到该演员阵容存在问题,那么我猜投射就是要走的路。 – 2010-09-08 12:52:58

相关问题