Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> библиотека шаблонов, не идет ссылка на элемент массива 
:(
    Опции темы
Andrej23
Дата 28.10.2010, 16:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 3.11.2006

Репутация: нет
Всего: нет



Доброго времени суток.

Собственно такая вот загвоздка вышла:

Пытаюсь сделать шаблон.
Шаблон сам нормально компилируется, но при его вызове vs2005 выдает ошибку: 

error C2597: illegal reference to non-static member 'Indicators::Regr'

Шаблон объявил так:
Код

template <typename T,typename Tb,typename Tv,typename Tvb,Tv T::*field,Tvb Tb::*fieldB> double StdDevRegTempl(long index, long Len, T const *array1, Tb const *arrayB);


Вызываю его так:

Код

//здесь выводится рассчитанное обычной ф-ией значение и хочу вывести следом значение, посчитанное шаблоном. 

printf ("StdDevReg:   %f template:  %f\n",Instr.i[500].sko_reg[0], StdDevRegTempl <class Tick, class Indicators, double, double, &Tick::Price, &Indicators::Regr[0]>(500,period,Instr.z, Instr.i));


компилятор на вызов шаблона ругается т.к.  Indicators::Regr - это массив из 20 элементов double, хотя и даю адрес конкретной ячейки массива (типа double).

собственно при вызове используются массивы с элементами типа класс. Сама структура:

Код

class Tick  
{
public:
    double  Price, Open,High,Low,Close;
};

class Indicators
{
public:
    double    Regr[20],    sko_reg[20];
};

class StockNumber
{
public:
    Tick z[NumQuotes];    //ряд тиковых данных, сейчас использую как минутки
    Indicators i[NumQuotes]; //класс с индикаторами
};

StockNumber Instr;


Как правильно изменить объявление ф-ии чтобы можно было задавать параметром элемент массива (чтобы можно было сказать &Indicators::Regr[0]  )?

Это сообщение отредактировал(а) Andrej23 - 28.10.2010, 16:36
PM MAIL   Вверх
Andrej23
Дата 28.10.2010, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 3.11.2006

Репутация: нет
Всего: нет



В принципе вызвал шаблон, считающий  значение  Indicators::Regr[0] прямо из шаблона StdDevRegTempl , но остался общий вопрос - как можно сделать вызов значения напрямую, без промежуточного расчета чтобы сделать шаблон StdDevRegTempl еще более общим.

Попробовал сделать кол-во элементов массива константой, не помогло:

Код

const int NumCellsInd = 20;

class Indicators
{
public:
    double    Regr[NumCellsInd],    sko_reg[NumCellsInd];
};


Всё равно пишет, что 

illegal reference to non-static member 'Indicators::Regr'

Это сообщение отредактировал(а) Andrej23 - 28.10.2010, 17:22
PM MAIL   Вверх
rudvil
Дата 28.10.2010, 20:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 20.11.2009
Где: Latvia/Riga

Репутация: 2
Всего: 3



Компилятор же пишет, что "так" использовать не-статические члены класса нельзя, соответственно нужно объявить их статическими.
Код
static double    Regr[NumCellsInd],    sko_reg[NumCellsInd];

--------------------
xor
PM MAIL Skype   Вверх
Andrej23
Дата 29.10.2010, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 3.11.2006

Репутация: нет
Всего: нет



У меня массив Instr.i[] с объектами этого класса. Если сделать члены класса статическими, то получится по одному экземпляру массива-члена класса на весь массив объектов этого класса.

Похоже пока что просто оставлю расчет с вызовом шаблона изнутри другого  шаблона. Работает медленнее, но работает.

А как перейду на с++, тогда по-другому попробую (несколько веток назад подсказали 2 варианта, возможно во втором варианте такой фокус пройдет).

Это сообщение отредактировал(а) Andrej23 - 29.10.2010, 15:41
PM MAIL   Вверх
Master01
Дата 29.10.2010, 19:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 22.8.2007

Репутация: 2
Всего: 2



Код

printf ("StdDevReg:   %f template:  %f\n",Instr.i[500].sko_reg[0], StdDevRegTempl <class Tick, class Indicators, double, double, &Tick::Price, &Indicators::Regr[0]>(500,period,Instr.z, Instr.i));


Очень маловероятно, что такой код вообще будет работать, поскольку все параметры шаблона должны быть известны в момент компиляции! А тут у вас передаётся адрес поля &Tick::Price и &Indicators::Regr[0] которые на этапе компиляции никак известны быть не могут.
PM MAIL   Вверх
Andrej23
Дата 1.11.2010, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 3.11.2006

Репутация: нет
Всего: нет



Цитата(Master01 @  29.10.2010,  19:15 Найти цитируемый пост)
у вас передаётся адрес поля &Tick::Price и &Indicators::Regr[0] которые на этапе компиляции никак известны быть не могут. 


Проблемы возникают только с адресом ячейки массива-члена класса. С членом класса Price никаких проблем не было.

Вот в этой ветке мне дали 2 примера, первый у меня отлично работает:

http://forum.vingrad.ru/forum/topic-313153...1%81%D0%B0.html

PM MAIL   Вверх
Master01
Дата 1.11.2010, 22:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 22.8.2007

Репутация: 2
Всего: 2



угу, признаю был не прав. Я просто вообще не в курсе был про ссылки на члены-данные класса ....

Я тут почитал Страуструпа smile И насколько я понимаю

Код

struct {
 int a[3]
 };

равносильно
Код

struct {
 int a[2];
 int addr; // -- вот это и будет именно то смещение которое вы искали для a[3]. (хотя не уверен если это гарантируется стандартом)
}

Так что можно, например, написать какой-то темплейт который будет автоматом разворачиваться в нечто подобное, а потом брать ссылку на этот самый addr и кастить через reinterpret_cast .... да простят меня великии за такое smile

Но это ужасно! и так делать не надо smile

Вообщем, я бы предложил вам лучше передавать ссылки не на сами членны-данные класса, а на некоторый метод класса, который их возвращает? Гибкость таже (и даже больше, так как метод может предварительно эти данные обработать ещё), но с другой стороны, придётся писать такие методы конечно...

Вот код, для примера (немного переработанный оригинальный код djamshud-а, взятый по той линке, что вы мне дали)
Код

#include<stdio.h>

struct Test
{
    double a;
    double b[3];
    double c;

    double get() const { return b[2]; }
};



template<typename T, typename Tv, Tv (T::*func)() const >
Tv sum(T const *arr, size_t len)
{
    Tv res = 0;

    for(size_t i = 0; i < len; i++)
        res += (arr[i].*func)();

    return res;
}

int main()
{
    Test arr_test[]={ {1, {10,20,30}, 5}, {4, {0.1, 0.2, 0.3}, 7} };  

    double res = sum<Test, double, &Test::get>
        (arr_test, sizeof(arr_test)/sizeof(*arr_test));
    
    printf("%f\n",res);

    return 0;
}



Спасибо за инфу про ссылки на члены-данные класса smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0819 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.