Russian Qt Forum
Ноябрь 24, 2024, 05:36 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2] 3 4   Вниз
  Печать  
Автор Тема: Про templat  (Прочитано 20818 раз)
Ced
Гость
« Ответ #15 : Май 07, 2017, 19:28 »

Еще раз прошу подсказки. Как можно внутри конструктора шаблона узнать, какой тип данных подан на вход?
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #16 : Май 07, 2017, 21:48 »

Например так
Код
C++ (Qt)
template <typename T>
class MyCoolClass {
public:
   MyCoolClass(const T &value)  
       : value_(value)
   {
   }
private:
   T value_;
};
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #17 : Май 07, 2017, 21:52 »

Igors,
Лучше не указывать void при отсутствии параметров в объявлении метода, функции.
1. Это pure c style
2. Это дезориентирует новичков.
Я знаю людей, которые свято верят, что в относительно старых версиях gcc без void в скобках код не скомпилируется.
Записан
Ced
Гость
« Ответ #18 : Май 07, 2017, 21:53 »

Например так
Код
C++ (Qt)
template <typename T>
class MyCoolClass {
public:
   MyCoolClass(const T &value)  
       : value_(value)
   {
   }
private:
   T value_;
};

Честно сказать, я не понял, как это работает. Может поясните?
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #19 : Май 07, 2017, 22:04 »

Есть шаблонный класс, который хранит в себе value_ типа T.
Тип T задаётся пользователем шаблона например так
Код
C++ (Qt)
double d = 123.0;
MyCoolClass<int> instance(d);
В примере шаблон инстанцируется типом int, конструктор принимает int конвертируя double по всем канонам Улыбающийся
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #20 : Май 07, 2017, 22:08 »

Можно конкретнее, что именно за задача стоит. Вдруг шаблоны и не нужны...
Записан
Ced
Гость
« Ответ #21 : Май 07, 2017, 22:09 »

Есть шаблонный класс, который хранит в себе value_ типа T.
Тип T задаётся пользователем шаблона например так
Код
C++ (Qt)
double d = 123.0;
MyCoolClass<int> instance(d);
В примере шаблон инстанцируется типом int, конструктор принимает int конвертируя double по всем канонам Улыбающийся

Или я Вас опять не понял, или плохо объяснил, чего хочу. Проблема вот в чем:
Некоторые операции не могут быть реализованы одинаково для различных типов данных. Это очевидно.
В конструкторе класса я совершаю с данными такие операции. Чтобы корректно обрабатывать различные типы, я хочу знать, каким типом инстанцирован тот конкретный объект, для которого сейчас запущен конструктор. Мне кажется, Ваш код эту проблему не решает. Мне нужно получить информацию об инстанцирующем типе в виде признака. по которому можно организовать ветвление алгоритма.
« Последнее редактирование: Май 07, 2017, 22:14 от Ced » Записан
Ced
Гость
« Ответ #22 : Май 07, 2017, 22:12 »

Можно конкретнее, что именно за задача стоит. Вдруг шаблоны и не нужны...

Обрабатывается поток данных. Данные поступают в виде строк. Каждая строка содержит набор значений. Значения эти могут быть разного типа и наперед их типы не известны. Для описания структуры потока используется специальный файл. Из него можно считать, что придет в потоке. При каждой обработке этот файл может быть различным.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #23 : Май 07, 2017, 22:24 »

Задачей не проникся.
Для определения типа:
Можно воспользоваться в крайнем случае
http://www.cplusplus.com/reference/type_traits/

Можно немножко усложнить шаблон путем специализации
Код
C++ (Qt)
template <typename T>
struct MyCoolFunctions;
Код
C++ (Qt)
template<>
struct MyCoolFunctions<float> {
   static doSomething(float value) {
       std::cout << value;
   }
};

Код
C++ (Qt)
template<>
struct MyCoolFunctions<double> {
   static doSomething(double value) {
       std::cerr << value;
   }
};
и т.д. специализируем все необходимые нам обработки

теперь сам шаблон
Код
C++ (Qt)
template<typename T, typename Traits=MyCoolFunctions<T>>
class MyCoolClass {
public:
   MyCoolClass(const T &value) {
       Traits::doSomething(value);
   }
}

инстанцируем так:
Код
C++ (Qt)
double d = 123;
float f = 456;
 
MyCoolClass<double> floatInstance (d); // cerr
MyCoolClass<float> floatInstance (f); // cout
 
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #24 : Май 07, 2017, 22:28 »

К слову, шаблоны - инструмент времени компиляции.
А чтение потоков и файлов происходит во время выполнения программы.
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #25 : Май 07, 2017, 22:31 »

Предлагаю подробнее разжевать задачу. Привести 2-3 примера, того что приходит в потоке данных и как при описании структуры используется файл (пример что он содержит).
Записан
Ced
Гость
« Ответ #26 : Май 07, 2017, 22:34 »

Для задачи я нашел решение. Оно конечно не универсально, но в моем случае вполне пригодно. Теперь интересуюсь уже из любопытства, есть ли что-то менее костыльное. Предложенные Вами способы честно говоря не очень порадовали. По ссылке описана возможность для многих типов, но я скажем не нашел там варианта узнать про тип bool. Второй способ таков, что можно и не пользоваться шаблонами. Просто ветвим алгоритм для каждого типа и все. Сейчас у меня есть ветвление при инстанцировании. Я считываю файл настроек, узнаю о типе каждого параметра и инстанцирую соответствующий класс в нужной ветке. Дальше все вроде красиво.
Записан
Ced
Гость
« Ответ #27 : Май 07, 2017, 22:39 »

Предлагаю подробнее разжевать задачу. Привести 2-3 примера, того что приходит в потоке данных и как при описании структуры используется файл (пример что он содержит).
Вот пример такого файла, если интересно
Код:
[Parametr]
[Name]
t
[Comment]
Время
[Type]
3
[Sorce]
0
[Parametr]
[Name]
MH
[Comment]
Наработка
[Type]
2
[Sorce]
2
[Parametr]
[Name]
R41
[Comment]
Тв на вх. Д (1)
[Dimention]
град. Цел.
[Type]
0
[Sorce]
0
[minPossible]
-50
[minMarginal]
-50
[maxMarginal]
50
[maxPossible]
50

А вот код, который его читает:
Код:
    QTextStream *in1 = new QTextStream(parametrsFile);
    while(!in1->atEnd())
    {
        ParametrName  temp (*in1);
        switch (temp.getType())
        {
    case Parametr<float>::continuous:
        {
            Parametr<float> tmp(*in1, temp);
            mainBuffer.append(new Parametr<float>(tmp));
            break;
        }
    case Parametr<bool>::discreteYesNo:
        {
            Parametr<bool> tmp(temp);
            mainBuffer.append(new Parametr<bool>(tmp));
            break;
        }
    case Parametr<long>::time:
        {
            Parametr<long> tmp(*in1, temp);
            mainBuffer.append(new Parametr<long>(tmp));
            break;
        }
    case Parametr<QDateTime>::dateTime:
        {
            Parametr<QDateTime> tmp(temp);
            mainBuffer.append(new Parametr<QDateTime>(tmp));
            break;
        }
    default:
            break;
        }
    }
« Последнее редактирование: Май 07, 2017, 22:42 от Ced » Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #28 : Май 07, 2017, 22:48 »

Ну, вроде, это единственный вариант делать именно то, что вы делаете.
Единственное, что могу предложить, это только сделать мапу данных и указателей на функцию типа:
Код
C++ (Qt)
template <typename T>
ParamBase *makeNewParam(const QString &value) {
return new Param<T>(value);
}
 

Код
C++ (Qt)
static const std::map<QString, std::function<ParamBase*(const QString &)> funMap= {
   "bool", makeNewParam<bool>,
   "int", makeNewParam<int>
};

Поведение конструктора Param описать с помощью Traits, как было написано выше.

Вызывать так
Код
C++ (Qt)
const QString type("bool");
const QString myData("data");
myParams += funMap.at(type)(myData);
« Последнее редактирование: Май 07, 2017, 22:50 от __Heaven__ » Записан
Ced
Гость
« Ответ #29 : Май 07, 2017, 22:51 »

Ну, вроде, это единственный вариант делать именно то, что вы делаете.
Единственное, что могу предложить, это только сделать мапу данных и указателей на функцию типа:
Код
C++ (Qt)
template <typename T>
ParamBase *makeNewParam(const QString &value) {
return new Param<T>(value);
}
 

Код
C++ (Qt)
static const std::map<QString, std::function<ParamBase*(const QString &)> funMap= {
   "bool", makeNewParam<bool>,
   "int", makeNewParam<int>
};

Поведение конструктора Param описать с помощью Traits, как было написано выше.

Вызывать так
Код
C++ (Qt)
const QString type("bool");
const QString myData("data");
funMap.at(type)(myData);

Спасибо. Это намотаю на ус. Думаю, пригодится, когда буду рефакторить эту писанину. Сейчас просто времени очень мало. Приходится лепить с листа. Качество кода меня лично удручает, но такими темпами я лучше не способен. Очень надеюсь, что будет возможность потом все это причесать.
Записан
Страниц: 1 [2] 3 4   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.566 секунд. Запросов: 23.