Вопрос к профессионалам

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Делаю класс для обращения к внешней I2C EEPROM, класс не шаблонный.  Хочу сделать шаблон индексатора в классе, чтобы ненапряжно отдавать из EEPROM значения разных типов. 

Пишу 

class AT24CXX{

public:

template<typename T>

T operator[](const int addr){ return допустим пока T();}

}

в основной программе пишу 

AT24CXX ExtEeprom;

float f = ExtEeprom[0];

int  i = ExtEeprom[2];

не компилится, ошибка предсказания шаблонного типа, хотя тип можно легко вывести из lvalue.

Если пишу так 

float f = ExtEeprom.operator[]<float>(0);

int  i = ExtEeprom.operator[]<int>(2);

работает прекрасно, но это некрасиво же.  Как сделать красивый индексатор? 

 

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Если честно в лоб, то никак: "Function declarations that differ only in the return type, the exception specification, or both cannot be overloaded" (ISO/IEC 14882:2017 16.1 (2.1)). И понятно почему, в тот момент, когда выбирается функция, ещё ничего неизвестно о типах контекста вызова. Можно ли как-то обмануть через зад, подумать надо.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

нет, я знаю, что перегрузка функций различающихся только типом возвращаемого значения не разрешена.  

Но ить это то что, как не функции, отличающиеся только типом возврата 

float f = ExtEeprom.operator[]<float>(0);

int  i = ExtEeprom.operator[]<int>(2);

и шаблон сгенерен правильно, и вызываются они правильные.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

в классе 

	template<typename T>
	T operator[](const int idx) {
		if (sizeof(T) == 4) return 111.00;
		else return 55;
	};

в сетапе 

void setup()
{
	Serial.begin(115200);
	Serial << F("Program started\n");

	findI2CDevice();

	Serial << "\nEEPROM Size = " << ExtEprom.Size << eoln;

	int f = ExtEprom.operator[]<int>(0);
	float r = ExtEprom.operator[]<float>(2);

	Serial << "Eprom reads f = " << f << "  r = " << r << eoln;

}

в порту 

 

Алексей.
Алексей. аватар
Offline
Зарегистрирован: 02.02.2018

DetSimen пишет:

Если пишу так
float f = ExtEeprom.operator[]<float>(0);
int  i = ExtEeprom.operator[]<int>(2);
работает прекрасно, но это некрасиво же.  Как сделать красивый индексатор?
А мне нравится, абсолютно однозначно указан вызываемый метод, шансов ошибиться не остаётся.
 

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

DetSimen пишет:

Но ить это то что, как не функции, отличающиеся только типом возврата 

float f = ExtEeprom.operator[]<float>(0);

int  i = ExtEeprom.operator[]<int>(2);

Так здесь нет вызова перегруженной функции. Здесь функция определена полностью, птоому "overload resolution" не применяется - функция вызывается прямо.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Никада я своими куриными мозгами не постигну этот лжывый С++, и никакой Страуструп не поможет. 

Я почему-то думал, что шаблоны разворачиваются в 

int f = ExtEprom.operator[]<int>(0);

int operator[](const int idx);


float r = ExtEprom.operator[]<float>(2);

float operator[](const int idx);

а они как раз только типом возврата и отличаюца. 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Правда, блин, лучше и легче ящики таскать, а вечером настойку пить.

wdrakula
wdrakula аватар
Онлайн
Зарегистрирован: 15.03.2016

Дед! Родное сердце! Помнишь анекдот про семью верблюдов:

-- Мам! А зачем нам такие широкие мохнатые копыта?

-- Это для того, чтобы мы могли долго идти по горячему песку пустыни, сынок.

-- Мам! А зачем нам такой густой мех?

-- Это для того, чтобы горячее солнце пустыни не обжигало нам кожу, сынок.

-- Мам! А зачем нам такой горб?

-- Чтобы мы могли долго не испытывать жажду и голод в пустыне, сынок.

-- Мам! А зачем нам весь этот тюнинг В ЗООПАРКЕ???

===========================================

Сёма! Ты ж контроллер программируешь. Тебя Пух укусил и теперь по ночам ООП с косой в углу стоит? ;))

Вот бери большой комп и на нём - знаю, ты C# любишь, я - Питон люблю. Там и декораторы и множественное наследование и динамическая типизация. Достижение оргазма програмистом - за 7 минут кодинга! ;))) А в "зоопарке" оно к чему?

И да, на С++ красиво индексатор не сделать... все равно тип придется как-то, хоть тушкой, хоть чучелом, но передать.

   Ты смотри от финала: допустим ты придумал и пишешь код, используя задумку. В этот момент ты написал

my_var = MyEEPROM [i];

Где ты тип возврата передал? Можно всякие извраты придумывать, но тип передать надо.

вот для такого использования, уже очевидно, как писать:

my_var = MyEEPROM.idx(my_var) [i];
или
my_var = MyEEPROM._float [i];

Да, это "не курасиво". ;))))

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Вот.  А задумка была, чтоб хоть байт, хоть структуру одним индексатором в епром ложить\класть.  

все равно не понимаю, тип lvalue на момент компиляции известен, чоб шаблон не сгенерить под его тип, если, канеш, переменная не обьявлена как auto, тогда да, можно и поругаца. 

Ладно, чо теперь, пойду стаканами крутить да размахивать. :(  

wdrakula
wdrakula аватар
Онлайн
Зарегистрирован: 15.03.2016

DetSimen пишет:
Ладно, чо теперь, пойду стаканами крутить да размахивать. :(  

Ты эт, береги себя! Меня вот аритмия замучила, так ужо вторые сутки трезвости пошли!

Спал - как младенец! (не в том смысле, чтоб всю ночь орать, а  под утро обоссаться ;)) )

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

DetSimen пишет:

все равно не понимаю, тип lvalue на момент компиляции известен, 

В том-то и дело, что неизвестен. Сначала вычислиются типы справа (иначе бы auto не работал). А как вычислить справа, если для его вычисления надо "слева" знать?

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

wdrakula пишет:
Тебя Пух укусил
Ну, не скажи. Видал очень красивое решение для библиотеки типа сайберлиба на шаблонах. Реально красиво сделано.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Спасибо. 

Придется шаблонами как в EEPROM put и get делать. 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

wdrakula пишет:

Дед! Родное сердце! Помнишь анекдот про семью верблюдов:

-- Мам! А зачем нам такие широкие мохнатые копыта?

-- Это для того, чтобы мы могли долго идти по горячему песку пустыни, сынок.

-- Мам! А зачем нам такой густой мех?

-- Это для того, чтобы горячее солнце пустыни не обжигало нам кожу, сынок.

-- Мам! А зачем нам такой горб?

-- Чтобы мы могли долго не испытывать жажду и голод в пустыне, сынок.

-- Мам! А зачем нам весь этот тюнинг В ЗООПАРКЕ???

===========================================

Потому что в мире капитализма этот ЗООПАРК закроется и придется ночевать на улице. И мохнатые копыта позволять не поранится на свалке, густой мех не замерзнуть на улице, а горб потому есть будешь не всегда каждый день. А пока радуйся сынок, что детство у тебя прошло в сытом зоопарке.И тюниг тоже здесь. Потому что тюнинг за пределами зоопарка стоит денег, который у тебя может не оказаться, потому что ты животное.