Лучший способ инициализировать унаследованный член класса var типа std :: array? - PullRequest
0 голосов
/ 03 сентября 2010

Сущность имеет член var типа std :: array. Студент наследует от 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"}}
        )
    {}
};

1 Ответ

1 голос
/ 06 сентября 2010

Есть два варианта, но один зависит от проверки размера во время выполнения.Обратите внимание, что последнее в моем примере эквивалентно приведению.Что не так с приведением типов?

#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_ ниже - что эквивалентно вашему текущему коду - или потребовать, чтобы он пережил и сохранил указатель / ссылку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...