Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
494 / 208 / 70
Регистрация: 27.05.2016
Сообщений: 554
1

Get для std::variant

26.11.2017, 15:37. Показов 1332. Ответов 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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.11.2017, 15:37
Ответы с готовыми решениями:

Операция std::cout для Объекта типа std::string
Кто детально объяснит почему не выводит ? Дает вот так &quot;Отсутствует оператор &quot;&lt;&lt;&quot;, соответствующий...

Не воспринимает ни std::cout, ни std::cin. Вобщем ничего из std. Также не понимает iostream
Здравствуйте! Я хотел начать изучать язык C++. Набрал литературы. Установил Microsoft Visual C++...

ошибка error: cannot convert 'std::string {aka std::basic_string<char>}' to 'std::string* {aka std::basic_stri
на вод поступают 2 строки типа string. определить количество вхождений строки 2 в строку 1 ошибка...

STL std::set, std::pair, std::make_pair
Я не знаю как описать тему в двух словах, поэтому не обращайте внимание на название темы....

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

Добавлено через 4 минуты
всё разобрался.
0
Любитель чаепитий
3624 / 1711 / 532
Регистрация: 24.08.2014
Сообщений: 5,786
Записей в блоге: 1
27.11.2017, 10:11 3
а можно узнать, зачем такое вообще понадобилось?
P.S. ваш второй код не компилируется.
http://coliru.stacked-crooked.... afa6b5dc1b
0
494 / 208 / 70
Регистрация: 27.05.2016
Сообщений: 554
27.11.2017, 14:31  [ТС] 4
Цитата Сообщение от GbaLog- Посмотреть сообщение
а можно узнать, зачем такое вообще понадобилось?
Ну я подумал, раз уж можно сделать вывод в рантайме без указания индекса (в компайл тайме) пользователем, то почему нельзя и возвратить нужное значение из метода. Но скорее всего такая магия не достижима, поскольку возвращаемый тип из метода должен быть известен на этапе компиляции. И в рантайме никак не получится, только непосредственно использовать в нужном месте.
Цитата Сообщение от GbaLog- Посмотреть сообщение
ваш второй код не компилируется.
Да, я знаю, - это просто был набросок.

Не по теме:

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

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.11.2017, 14:31

На основе исходного std::vector<std::string> содержащего числа, создать std::vector<int> с этими же числами
подскажите есть вот такая задача. Есть список . Создать второй список, в котором будут все эти же...

Что означает Variant (для перевода на другой ЯП)
Есть следующий код: Dim OriginArray(1 To 3) As Variant Dim Origin(1 To 2) As Double '. . . ....

Std::bind, std::mem_fun, std::mem_fn
В чем разница между функциями std::bind, std::mem_fun, std::mem_fn?

Std::begin() ,std::end(),std::copy
...// int main() { std::vector&lt;double&gt; data;//Работает cout &lt;&lt; std::begin(data); ...


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

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

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