Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++
Войти
Регистрация
Восстановить пароль
 
notAll
450 / 171 / 62
Регистрация: 27.05.2016
Сообщений: 456
Завершенные тесты: 2
#1

Get для std::variant

26.11.2017, 15:37. Просмотров 316. Ответов 3
Метки нет (Все метки)

Задача: сделать простой метод get() без параметров, который буде возвращать установленное в std::variant значение. У меня получилось как то так:
C++
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
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <string>
#include <variant>
#include <utility>
#include <type_traits>
#include <cassert>
 
template <typename ... SupportedTypes>
class MyTypes
{
private:
    std::variant<SupportedTypes ...> m_var;
    int m_index = 0;
 
    template <std::size_t I, typename = std::enable_if_t<I == std::variant_size_v<decltype(m_var)>>>
    void get_impl(int id, int *fake = nullptr) const
    {}
 
    template <std::size_t I = 0, typename = std::enable_if_t<I < std::variant_size_v<decltype(m_var)>>>
    void [INLINE]get_impl[/INLINE](int id) const
    {
        if (m_index == id) std::cout << std::get<I>(m_var);
 
        get_impl<I + 1>(id + 1);
    }
 
public:
    template <typename T>
    void init(T&& param)
    {
        m_var = std::forward<T>(param);
        m_index = m_var.index();
    }
 
    int index() const noexcept { return m_index; }
 
    void get() const { get_impl<0>(0); }
};
 
 
int main()
{
    MyTypes<int, double, std::string> a;
    a.init("Hello");
    assert(a.index() == 2);
 
    a.get();
}
Но нужно чтобы метод get() возвращал значение, а не просто выводил его в поток в своей реализации. Плюс, можно ли реализовать get_impl как то более элегантней?

Добавлено через 28 минут
Возможно должно быть как то так:
Кликните здесь для просмотра всего текста
C++
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
template <typename ... SupportedTypes>
class MyTypes
{
private:
    std::variant<SupportedTypes ...> m_var;
    int m_index = 0;
 
    template <typename var_t = decltype(m_var)>
    constexpr static std::size_t var_size = std::variant_size_v<var_t>;
 
    template <std::size_t I>
    auto get_impl(int id, int *fake = nullptr) const -> std::enable_if_t<I == var_size<>, std::variant_alternative_t<I, decltype(m_var)>>
    {}
 
    template <std::size_t I = 0>
    auto get_impl(int id) const -> std::enable_if_t<I < var_size<>, std::variant_alternative_t<I, decltype(m_var)>>
    {
        if (m_index == id) return std::get<I>(m_var);
 
        return get_impl<I + 1>(id + 1);
    }
 
public:
    template <typename T>
    void init(T&& param)
    {
        m_var = std::forward<T>(param);
        m_index = m_var.index();
    }
 
    int index() const noexcept { return m_index; }
 
     auto get() const { return get_impl(0); }
};
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.11.2017, 15:37
Ответы с готовыми решениями:

std::string, std::fstream, ошибка кучи
где то начало вылетать при операции += с локальной переменной std::string....

Как проинициализировать std::stack<const int> obj ( std::stack<int>{} );
добрый день. вопрос в коде: http://rextester.com/VCVVML6656 #include...

std::filesystem && std::asio и пр
Пытался найти хоть какие-то сроки включения всего этого в стандарт (так же...

std::defaultfloat
Есть такая тема в новом стандарте как std::defaultfloat Описание:...

Вопрос по std::map
В качестве хэш-таблицы для строк (AnsiString) я использовал std::map. От...

3
Pechkin80
19 / 18 / 7
Регистрация: 14.03.2014
Сообщений: 251
26.11.2017, 21:36 #2
notAll, Извините что не совсем по теме, а этот std::variant сильно отличается от
http://itnotesblog.ru/note.php?id=213#sthash.mc6U6x4B.dpbs ?

Добавлено через 4 минуты
всё разобрался.
0
GbaLog-
Любитель чаепитий
3164 / 1470 / 465
Регистрация: 24.08.2014
Сообщений: 5,200
Записей в блоге: 1
Завершенные тесты: 2
27.11.2017, 10:11 #3
а можно узнать, зачем такое вообще понадобилось?
P.S. ваш второй код не компилируется.
http://coliru.stacked-crooked.com/a/82ffb2afa6b5dc1b
0
notAll
450 / 171 / 62
Регистрация: 27.05.2016
Сообщений: 456
Завершенные тесты: 2
27.11.2017, 14:31  [ТС] #4
Цитата Сообщение от GbaLog- Посмотреть сообщение
а можно узнать, зачем такое вообще понадобилось?
Ну я подумал, раз уж можно сделать вывод в рантайме без указания индекса (в компайл тайме) пользователем, то почему нельзя и возвратить нужное значение из метода. Но скорее всего такая магия не достижима, поскольку возвращаемый тип из метода должен быть известен на этапе компиляции. И в рантайме никак не получится, только непосредственно использовать в нужном месте.
Цитата Сообщение от GbaLog- Посмотреть сообщение
ваш второй код не компилируется.
Да, я знаю, - это просто был набросок.

Не по теме:

И можно на ты :)

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.11.2017, 14:31

Std::promise::set_exception
Пример с Хабра (вот из этой статьи): #include &lt;iostream&gt; #include &lt;thread&gt;...

переписать std::map
Добрый вечер! Есть работающая программа, в которой используется map, все...

Создание объекта std::set
http://www.cplusplus.com/reference/stl/set/set/ Вот официальный сайт,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru