LINUX.ORG.RU

[c++] extern std::complex<T> arr[]

 


0

0

Пытаюсь передать extern-ом из одного файла в другой массив комплексных чисел следующим образом:

file1.cpp:
#define C(x,y) std::complex<double>((x),(y))
const int N = 2;
std::complex<double> сarr[N] = {C(0.,5.), C(5.,0.)};

file2.cpp:

extern std::complex<double> carr[];
std::myvec< complex<double> >* _par = new myvec< complex<double> > (carr,2);

/* конструктор myvec(T*, const int&) существует */


так вот... с double эта конструкция работала, но когда я изменил тип данных с double на complex, передаётся массиф правильного размера, но содержащий одни нули. Что я делаю не так?

anonymous

Я бы не стал так делать вот по какой причине: порядок инициализации
глобальных переменных не определен между единицами трасляции. 
Может так случиться (и скорее всего именно это и случается) что 
переменная _par в file2.cpp инициализируется до того как 
проинициализируется carr в file1.cpp.

Отчасти Вам может помочь такой прием:

file1.cpp:
std::complex<double>& GetCarr()
{
    static std::complex<double> сarr[N] = {C(0.,5.), C(5.,0.)};
    return carr;
}

file2.cpp
std::complex<double>& GetCarr(); // delcare it

std::myvec< complex<double> >* _par 
  = new myvec< complex<double> > (GetCarr(), 2);

В этом случае правильный порядок инициализации будет гарантирован.

anonymous
()
Ответ на: комментарий от anonymous

Да, я тоже думал, что инициализация происходит не в том порядке, в котором я ожидаю, смутил меня только тот факт, что с double оно всегда работало. Статиком я его не объявил, потому что предусмотрена ещё опция, которой массив заполняется значениями, считанными из файла. Буду думать, как переделать ваш пример под это условие и курить man extern.

anonymous
()
Ответ на: комментарий от anonymous

контейнеры STL не предполагают наследования. адаптация за счёт агрегации, и никак иначе,- в противном случае проблем у тебя будет ещё очень много

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

>контейнеры STL не предполагают наследования.

Чёрт, действительно. Я этого не знал. Придётся от наследования отказаться. А что значит "адаптация за счёт агрегации"?

anonymous
()
Ответ на: комментарий от jtootf

контейнеры stl допускают наследование. да, это плохой стиль, - но стандарт не запрещает наследоваться от них.

anonymous
()
Ответ на: комментарий от anonymous

порядок мог поменяться, например, из-за того что линковщику теперь (с такими типами и такими зависимостями) так показалось удобнее.

anonymous
()
Ответ на: комментарий от anonymous

Так не компилится.
Делаю так:

file1.cpp:
std::complex<double>* get_carr()
{
  static std::complex<double> carr[2] = {C(1,0), C(0,1)};     (1)
  return carr;                                                (2)
}


file2.cpp:
std::complex<double>* get_carr();
td::myvec< complex<double> >* _par = new myvec< std::complex<double> > (get_carr(), 2);

Уже при компиляции получаю: 
(1): warning: unused variable 'carr'
и соответственно
(2): error: 'carr' was not declared in this scope

Не думал, что с таким казалось бы несложным действием будет столько геморроя

anonymous
()
Ответ на: комментарий от jtootf

Если не пытаться такие расширенные контейнеры использовать полиморфно, то проблем не будет. Не всегда же есть время и желание, чтобы переопределить все методы для использования агрегации :)

Reset ★★★★★
()
Ответ на: комментарий от Reset

Победил я эту подлую штуку. Точнее, она меня. Теперь массив инициируется как static во втором файле, там, где он собственно и нужен, а в первом не упоминается вообще.
Спасибо всем за помощь и советы. 

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.