powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Определение по типу переменной, в которую возвращается значение
17 сообщений из 17, страница 1 из 1
Определение по типу переменной, в которую возвращается значение
    #39443050
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть такая примерная иерархия классов:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
class A
{
	typeA a_;
};

class B
{
	typeB a_;
};

class C
{
	typeC a_;
};


Можно ли как-то написать функцию Get, чтобы можно было вызывать так:
Код: plaintext
1.
2.
3.
4.
C c;
typeA a = c.Get(); // returns A::a_;
typeB b = c.Get(); // returns B::a_;
typeC c = c.Get(); // returns C::a_;


?

У меня получилось максимум сделать функцию-шаблон, куда передаётся тип класса (A,B,C) и из него возвращается соответствующая переменная. Но в общем случае мы не видим связь между именем класса и типом переменной. Наверно, можно попробовать сделать иерархию на основе шаблона класса, куда передавать тип (typeA, typeB, typeC), но не совсем понятно, как.
...
Рейтинг: 0 / 0
Определение по типу переменной, в которую возвращается значение
    #39443081
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
#include <iostream>
typedef int typeA;
typedef struct { int a, b; } typeB;


template <typename T> class A 
{
public:
	T a_;
	virtual T Get() = 0;
};

class realA : A<typeA>
{
public:
    realA() { a_ = 777; }
	typeA Get(){ return a_; }
};

class realB : A<typeB>
{
public:
    realB() { a_.a = 888; }
	typeB Get(){ return a_; }
};

int main()
{
	realA x;
	realB y;
	auto test = x.Get();
	auto test2 = y.Get();
	std::cout << test << std::endl;
	std::cout << test2.a << std::endl;
}
...
Рейтинг: 0 / 0
Определение по типу переменной, в которую возвращается значение
    #39443111
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbЕсть такая примерная иерархия классов:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
class A
{
	typeA a_;
};

class B
{
	typeB a_;
};

class C
{
	typeC a_;
};


Можно ли как-то написать функцию Get, чтобы можно было вызывать так:
Код: plaintext
1.
2.
3.
4.
C c;
typeA a = c.Get(); // returns A::a_;
typeB b = c.Get(); // returns B::a_;
typeC c = c.Get(); // returns C::a_;


?

У меня получилось максимум сделать функцию-шаблон, куда передаётся тип класса (A,B,C) и из него возвращается соответствующая переменная. Но в общем случае мы не видим связь между именем класса и типом переменной. Наверно, можно попробовать сделать иерархию на основе шаблона класса, куда передавать тип (typeA, typeB, typeC), но не совсем понятно, как.


Обычный статический метод тебе тут подойдёт.
Правда, код будет малополезен. Он будет малополезен в любом случае, везде тебе нужно будет явно в вызове указывать статический тип класса, которого ты хочешь узнать "тип". Динамический тип у тебя везде тут C, и статический тип переменной -- С.

Ещё вариант -- простая невиртуальная функция с явным приведением типа при вызове или явным указанием скоупа класса при вызове. Эффект будет тот же -- тип придётся указывать, и толку в том, что ты вызовешь ещё функцию -- ноль.
...
Рейтинг: 0 / 0
Определение по типу переменной, в которую возвращается значение
    #39443113
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbУ меня получилось максимум сделать функцию-шаблон, куда передаётся тип класса (A,B,C) и из него возвращается соответствующая переменная. Но в общем случае мы не видим связь между именем класса и типом переменной. Наверно, можно попробовать сделать иерархию на основе шаблона класса, куда передавать тип (typeA, typeB, typeC), но не совсем понятно, как.

Не понятно вообще, что ты тут хочешь.

Получить тип класса, тип которого ты уже и так знаешь ?
...
Рейтинг: 0 / 0
Определение по типу переменной, в которую возвращается значение
    #39443125
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SiemarglНе, это не то
MasterZivПолучить тип класса, тип которого ты уже и так знаешь ?да, но сделать менее перегруженный код. Т.е, как я уже писал, работает в таком виде:
Код: plaintext
1.
2.
3.
4.
C c;
typeA a = c.Get<typeA>(); // returns A::a_;
typeB b = c.Get<typeB>(); // returns B::a_;
typeC c1 = c.Get<typeC>(); // returns C::a_;

но приходится 2 раза указывать класс.
можно, наверно, сверху обернуть шаблоном, который будет 2 раза этот тип указывать, чтобы наружу ничего не торчало.
можно (точно) делать фунцию Get и параметром передавать туда переменную требуемого типа. Но тогда придётся в одну строку писать декларацию, во вторую вызов Get. И я не смогу возвращать ссылки, а хотелось бы.

И кроме того, я ж могу ошибиться и написать:
Код: plaintext
1.
2.
3.
4.
C c;
typeA a = c.Get<typeC>(); // 
typeB b = c.Get<typeA>(); // 
typeC c1 = c.Get<typeB>(); // 

и если есть касты между типами, я это так и не замечу при компиляции
...
Рейтинг: 0 / 0
Определение по типу переменной, в которую возвращается значение
    #39443133
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMb,

Код: plaintext
1.
auto a = c.Get<typeA>();
...
Рейтинг: 0 / 0
Определение по типу переменной, в которую возвращается значение
    #39443140
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
Код: plaintext
1.
auto a = c.Get<typeA>();

Шах и мат
Даже нечего возразить
...
Рейтинг: 0 / 0
Определение по типу переменной, в которую возвращается значение
    #39443165
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbДаже нечего возразить
А ты усложни задачу, введя указатели. Слабо написать так:
Код: sql
1.
std::unique_ptr<auto> a(c.Get<TypeA>());


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Определение по типу переменной, в которую возвращается значение
    #39443183
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovА ты усложни задачуя ещё толком на шаблонах первый вариант не написал, и у меня цель не усложнять, а упрощать :)
Проблема с шаблонами в том, что при вызове мы совсем не знаем, из какого типа нам звать функцию Get.
...
Рейтинг: 0 / 0
Определение по типу переменной, в которую возвращается значение
    #39443274
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проблема вот в чём. Мы хотим иметь более общий вариант описания объекта, чтобы не заводить кучу иерархий классов на каждую цепочку. Т.е. чтобы объявлять так:
Код: plaintext
1.
D<int, vector<float>, string> d;

или ещё как
изначально задумка была сделать класс, который можно наполнять любыми данными и получать их одной и той же функцией, определяя тип возвращаемого значения по типу переменной, что стоит слева(ещё более изначальная задумка была разделить данные в классе так, чтобы различные блоки кода могли обращаться только к своим типам данных извне, и всё работало быстро со статической типизацией)

я надеваю свой шаблонный плащ и шаблонную шляпу...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
template <typename... TS> class D{};
template <typename T1, typename... TS> class D<T1>: public <TS...>
{
	T1 a_;
protected:
	T1& _Get() {return a_;}
public:
	template <typename T> decltype(T::a_)& Get() {return T::_Get();}
};



всё ок, но тип мы определить не можем тут:
Код: plaintext
1.
2.
3.
D <int, string> d;
auto a = d.Get<string>();
auto b = d.Get<int>();// тут



Потому что у нас нету типа D<int> в иерархии, только D<string> и D<int, string> и извлечь из второго правильный тип для переменной a_ не получится (я сделал variadic template и для функции и несколько раз уронил компилятор,... но на вид это решило бы проблему совместимости типов, хотя и криво)

Решение проблемы весьма изящно!
Заводим ещё один шаблон, который будет нести информацию, а изначальный оставляем в качестве интерфейса:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
template <typename... TS> class D {};
template <typename T> class DS
{
	T a_;
protected:
	T& _Get() { return a_; }
};
template <typename T1, typename... TS> class D<T1, TS...>: public DS<T1>, public D<TS...>
{
public:
	template<typename T> decltype(DS<T>::a_)& Get() { return DS<T>::_Get(); }
};
...
Рейтинг: 0 / 0
Определение по типу переменной, в которую возвращается значение
    #39443329
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMb,

Это называется изящно???

Перегрузка по возвращаемому значению не зря же запрещена.

Может надо было по старинке?
Код: plaintext
1.
void Get(TypeA &retval)
...
Рейтинг: 0 / 0
Определение по типу переменной, в которую возвращается значение
    #39443374
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMb,

Еще возможна такая конструкция.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
struct A {};
struct B {};

struct S {
    template <typename T> operator T()
    {
        return T();
    }
};


int main()
{
    S s;
    A a = s;
    B b = s;

    return 0;
}
...
Рейтинг: 0 / 0
Определение по типу переменной, в которую возвращается значение
    #39443389
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На всякий уточняю что я имел в виду, что ваш метод get() должен возвращать S, который умеет приводиться к нужному типу.
...
Рейтинг: 0 / 0
Определение по типу переменной, в которую возвращается значение
    #39443760
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SiemarglЭто называется изящно???Ну да, довольно сложная конструкция, записанная в пять строчек. В чём и прелесть новых плюсов.
Давайте разберёмся, что не так в этой конструкции?SiemarglПерегрузка по возвращаемому значению не зря же запрещена.А, кстати, почему? Сидел, вспоминал, так и не вспомнил причину.
SiemarglМожет надо было по старинке?Да, можно и так, но я выше про это писал, тут есть 2 неудобства: запись в две строчки(decl + get), невозможность вернуть ссылку.Anatoly Moskovskyметод get() должен возвращать S, который умеет приводиться к нужному типунемного не совсем то. Т.е. как я понял, внутри S должны быть какие-то данные, в моём случае любые, int, vector<float>, string и потом как-то через operator T() должны кастоваться в T. Вот момент каста мне неясен. И у меня задумка другая: чёткая типизация. В 4-м посте я писал, что как раз стараюсь избежать любых кастов, чтобы автоматически избежать любых неявных ошибок.
...
Рейтинг: 0 / 0
Определение по типу переменной, в которую возвращается значение
    #39443819
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMb
Код: plaintext
1.
D<int, vector<float>, string> d;

И странно, что никто не сказал: "так это же tuple!" :)
Да, но хотелось пойти немного дальше, использовать типы-параметры как типы для векторов(а не просто переменных), а так же сделать методы для работы с этими векторами напрямую, не извлекая вектор из класса, что с tuple невозможно.
...
Рейтинг: 0 / 0
Определение по типу переменной, в которую возвращается значение
    #39443839
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbнемного не совсем то. Т.е. как я понял, внутри S должны быть какие-то данные
Нет. Там нужна всего лишь ссылка на c.
А дальше вы сами писали что у вас
CEMbработает в таком виде:
Код: plaintext
1.
2.
3.
4.
C c;
typeA a = c.Get<typeA>(); // returns A::a_;
typeB b = c.Get<typeB>(); // returns B::a_;
typeC c1 = c.Get<typeC>(); // returns C::a_;


но приходится 2 раза указывать класс.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
struct A {};
struct B {};

struct C {
   S get()
   {
        return S(*this);
   }
   template <typename T> T Get();  // это уже есть
};

struct S {
    C& c;
    S(C& c): c(c) {}
    template <typename T> operator T()
    {
        return c.Get<T>();
    }
};

int main()
{
    C c;
    A a = c.get();
    B b = c.get();

    return 0;
}
...
Рейтинг: 0 / 0
Определение по типу переменной, в которую возвращается значение
    #39445808
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky, ага, работает. Даже можно в C сразу operator T() вставить.
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Определение по типу переменной, в которую возвращается значение
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]