Re: Вопрос про конструкторы
От: prog123 Европа  
Дата: 07.08.19 20:25
Оценка:
Здравствуйте, Videoman, Вы писали:

нужен не експлисит к-тор или експлисит к твоему классу. сделай свой класс от вектора, типа такого

#include <vector>
#include <string>
#include <iostream>

using StrVector = std::vector<std::string>;

struct A
{
    operator size_t() const { return data_.size(); }
    operator StrVector() const { return data_; }
    std::vector<std::string> data_;
};

struct MyVector: public StrVector
{
    explicit MyVector(A const& a) : StrVector(a.data_){}
};

int main()
{
    A a{{"one"}};
    //StrVector v2(a);
    StrVector v2{MyVector{a}};
    for(auto const& e: v2)
        std::cout << e << std::endl; 
    return 0;
}
Re[4]: Вопрос про конструкторы
От: Videoman Россия https://hts.tv/
Дата: 08.08.19 08:09
Оценка:
Здравствуйте, night beast, Вы писали:

NB>неявные операторы приведения могут принести некоторые неожиданные проблемы.

NB>вспомни пример каста в булу в optional.

Полностью с вами согласен, в общем не стоит так делать, но тут у меня подобие библиотеки сериализации, и там все-равно тип динамически проверяется и если-что летит исключение. Просто не хочется указывать типы два раза, особенно потому что они длинные. Хочется типа type lazy deduction.
Re[2]: Вопрос про конструкторы
От: Videoman Россия https://hts.tv/
Дата: 08.08.19 08:11
Оценка:
Здравствуйте, prog123, Вы писали:

P>...


Спасибо, но такое решение мне не подойдет. Я уже описал выше почему.
Re[5]: Вопрос про конструкторы
От: night beast СССР  
Дата: 08.08.19 08:22
Оценка:
Здравствуйте, Videoman, Вы писали:

NB>>неявные операторы приведения могут принести некоторые неожиданные проблемы.

NB>>вспомни пример каста в булу в optional.

V>Полностью с вами согласен, в общем не стоит так делать, но тут у меня подобие библиотеки сериализации, и там все-равно тип динамически проверяется и если-что летит исключение. Просто не хочется указывать типы два раза, особенно потому что они длинные. Хочется типа type lazy deduction.


можно сделать функцию, которая возвращает обертку над A, у которой будет только один оператор каста.
Re: Вопрос про конструкторы
От: Videoman Россия https://hts.tv/
Дата: 08.08.19 08:24
Оценка:
Вроде нашел прототип решения:
struct A
    {
        operator const char&() const { return ch; }
        operator const size_t&() const { return sz; }
        operator const std::vector<std::string>&() const { return vec; }

        char ch;
        size_t sz;
        std::vector<std::string> vec;
    };

    struct B
    {
        B(const A& a) : v(a) {}

        std::vector<std::string> v;
    };

    // Где-то ниже
    A a;
    std::vector<string_t> v1 = a;
    std::vector<string_t> v2(a);
    B b(a);

На сомом деле такая штука работает, как ни странно. Т.к. у меня все-равно возвращается прокси шаблонный объект, то на практике типы ch, sz и vec сольются в один.
Остался вопрос к спецам, это норм, или опять глюки VS2017 ?

P.S. не , поспешил. Все-таки осталась задача как вернуть константную ссылку на временный объект. Прокси при своем создании еще не знает тип который будут запрашивать
Отредактировано 08.08.2019 8:32 Videoman . Предыдущая версия . Еще …
Отредактировано 08.08.2019 8:30 Videoman . Предыдущая версия .
Отредактировано 08.08.2019 8:26 Videoman . Предыдущая версия .
Re[2]: Вопрос про конструкторы
От: Videoman Россия https://hts.tv/
Дата: 08.08.19 08:52
Оценка:
Даже вот такое чудо работает, но очень нужно мнение, насколько это правильно ???:
#include <string>
#include <vector>
#include <iostream>

template <typename Type>
    struct Stub
    {
        Stub(Type type) : type(type) {}

        operator const Type&() const { return type; };

        Type type;
    };

    struct A
    {
        operator const size_t& () const { return Stub<size_t>({}); }
        operator const std::vector<std::string>& () const { return Stub<std::vector<std::string>>({}); }
    };

    struct B
    {
        B(const A& a) : v(a) {}

        std::vector<std::string> v;
    };

int main()
{
    // Где-то ниже
    A a;
    std::vector<std::string> v1 = a; // (1)
    std::vector<std::string> v2(a);  // (2)
    v1 = a;                          // (3)
    
    B b(a);
    
}


P.S. Глянул ассемблерный листинг внимательно. Вроде не работает как нужно. Деструктор Stub вызывается перед выходом, до return .
Отредактировано 08.08.2019 9:21 Videoman . Предыдущая версия .
Re[3]: Вопрос про конструкторы
От: andrey.desman  
Дата: 08.08.19 09:13
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Самое обидное, что:

V>
V>(3) [Type...] a; a = v2; // (Assign) Ok
V>


А, кстати, почему бы не сделать просто присваиванием?
Пустой вектор конструируется бесплатно. Присваивание будет через move-assign, которое тоже считай бесплатно.
Re[4]: Вопрос про конструкторы
От: Videoman Россия https://hts.tv/
Дата: 08.08.19 09:19
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>А, кстати, почему бы не сделать просто присваиванием?

AD>Пустой вектор конструируется бесплатно. Присваивание будет через move-assign, которое тоже считай бесплатно.

Пока так и сделал. Проблемы только истетические. Ну и хотелось просто у коллег проконсультироваться не упустил ли чего.
Варинт (2) — v2(a) тоже работает, но не всегда, иногда возникает неоднозначность. Короче зависит от конструкторов класса v2.
Re[5]: Вопрос про конструкторы
От: antonio_v_krasnom Россия  
Дата: 09.08.19 10:15
Оценка:
Здравствуйте, Videoman, Вы писали:

SVZ>>Вообще не люблю каст операторы. Очень много сюрпризов несут в себе.

SVZ>>В 99% случаев можно сделать нормальные мембер функции, возвращающие нужные данные.

V>Спасибо! Ну вот такого вот каста и хотелось бы избежать. В реальности у меня там очень навороченные и длинные шаблоны. А по поводу первого вопроса, можете пояснить? Может быть можно как-то исхитриться и не указывать весть тип в рамках С++17 ?


Простое решение в лоб — это:
1. Если есть возможность вносить изменения в сам класс А, то вместо неявного преобразования к вектору (или плюс к неявному, если вместо будет ломать много кода) сделать явное: A::ToVector(), и его и вызывать. В идеале лучше вместо — меньше сюрпризов потом будет.
2. Если редактировать класс А нельзя (сторонняя библиотека или иные причины), то добавить обычную функцию
std::vector<std::string> AToVector(const A&);
и явно её вызывать.

Вроде описанную тобой проблему решает.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.