2010-09-03 2 views
0

У объекта есть член var типа std :: array. Студент наследует от Entity, и ему нужно будет инициализировать элемент std :: array, который он унаследовал. Ниже приведен код, который я использую для этого, но он включает в себя вставку списка в скобках в std :: array. Я не уверен, что это правильный или оптимальный способ сделать это. Использование списка, заключенного в фигурные скобки или в виде двойной скобки без результатов приведения в ошибки компиляции. Я пробовал несколько других способов инициализации элемента std :: array var без успеха, поэтому, похоже, я придерживаюсь своего текущего метода. Есть ли лучший способ сделать это ?:Лучший способ инициализировать наследуемый элемент класса var типа std :: array?

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'. –

+0

Я вижу, где я мог бы использовать typedef для имени, но мог ли я сделать это для source_names? Спасибо за предложение, кстати. Всегда можно использовать больше советов. –

+0

'typedef array source_names_type;' –

ответ

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 :: array vs raw arrays. Не совсем уверен, чего нет, чтобы избежать. В любом случае, спасибо. Если никто не видит проблемы с этим приводом, учитывая сценарий, который я нарисовал, то я думаю, что кастинг - это путь. –

Смежные вопросы