оператор приведения типа
От: collider  
Дата: 27.01.19 19:29
Оценка:
Здравствуйте.

Может кто знает, как справиться с таким недугом, без явного указания?
компилятор VS 2015.

#include <string>

struct TestStruct
{

    template<class V>
    operator V&()
    {
        return V();
    }
    template<class V>
    operator const V&() const
    {
        return V();
    }
};

int main()
{
    TestStruct val;
    std::string str = val; //работает
    str = val; //а вот тут вот, говорит:  error C2593: 'operator =' is ambiguous. Есть варианты чтобы не писать str=(std::string)val; ? 
    return 0;
}
Re: оператор приведения типа
От: kov_serg Россия  
Дата: 27.01.19 19:53
Оценка: +8
Здравствуйте, collider, Вы писали:

C>
    template<class V>
    operator const V&() const
    {
        return V();
C>Есть варианты чтобы не писать?

Да. Никогда так не пишите.
Re: оператор приведения типа
От: _NN_ www.nemerleweb.com
Дата: 27.01.19 21:12
Оценка:
Здравствуйте, collider, Вы писали:

А ещё GCC/Clang не компилируют это
std::string str ( val );


Какую задачу решаем таким способом ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: оператор приведения типа
От: collider  
Дата: 28.01.19 04:21
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, collider, Вы писали:


_NN>А ещё GCC/Clang не компилируют это

_NN>
_NN>std::string str ( val );
_NN>


_NN>Какую задачу решаем таким способом ?

Что то типа std::any, но со своими нюансами.

Хотелось сделать более удобным в использовании(если можно привести то возвращаем, нет- exception),без использования cast-ов.
Re[3]: оператор приведения типа
От: rg45 СССР  
Дата: 28.01.19 10:03
Оценка: +3
Здравствуйте, collider, Вы писали:

C>Что то типа std::any, но со своими нюансами.

C>Хотелось сделать более удобным в использовании(если можно привести то возвращаем, нет- exception),без использования cast-ов.

Неявные преобразования — штука очень коварная, зачастую приносят вреда больше, чем пользы. Проблема неявных проразований много обсуждалась на протяжении многих лет. Как итог этих обсуждений можно рассматривать вот такое правило:

https://doc.lagout.org/programmation/C/CPP101.pdf

40. Avoid providing implicit conversions.

Summary
Not all change is progress: Implicit conversions can often do more damage than good. Think twice before providing implicit conversions to and from the types you define, and prefer to rely on explicit conversions (explicit constructors and named conversion functions).


Исключения из правила, конечно же, найти можно, но при этом нужно четко представлять себе все последствия такого дизайна. В std::any неявные преобразования не используются вовсе не потому, что авторы стандартной библиотеки не знают о существовании пользовательских операторов приведения типа
--
Re[4]: оператор приведения типа
От: collider  
Дата: 28.01.19 11:21
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, collider, Вы писали:


C>>Что то типа std::any, но со своими нюансами.

C>>Хотелось сделать более удобным в использовании(если можно привести то возвращаем, нет- exception),без использования cast-ов.

R>Неявные преобразования — штука очень коварная, зачастую приносят вреда больше, чем пользы. Проблема неявных проразований много обсуждалась на протяжении многих лет. Как итог этих обсуждений можно рассматривать вот такое правило:


R>https://doc.lagout.org/programmation/C/CPP101.pdf


R>

R>

40. Avoid providing implicit conversions.

R>
Summary
R>Not all change is progress: Implicit conversions can often do more damage than good. Think twice before providing implicit conversions to and from the types you define, and prefer to rely on explicit conversions (explicit constructors and named conversion functions).


R>Исключения из правила, конечно же, найти можно, но при этом нужно четко представлять себе все последствия такого дизайна. В std::any неявные преобразования не используются вовсе не потому, что авторы стандартной библиотеки не знают о существовании пользовательских операторов приведения типа



Спасибо за ваш ответ и за предостережения, но мой вопрос изначально был несколько другим
Я так понимаю, нынешние компиляторы не способны выбрать нужную конкретизацию в такой ситуации и никакими ухищрениями типа SFINAE не поможешь.
Я правильно понимаю?
Re[5]: оператор приведения типа
От: B0FEE664  
Дата: 28.01.19 12:54
Оценка: +1
Здравствуйте, collider, Вы писали:

C>Спасибо за ваш ответ и за предостережения, но мой вопрос изначально был несколько другим

C>Я так понимаю, нынешние компиляторы не способны выбрать нужную конкретизацию в такой ситуации и никакими ухищрениями типа SFINAE не поможешь.
C>Я правильно понимаю?

Вы так пишите, что можно подумать, что человек может выбрать нужную вам конкретизацию. Справа от оператора присваивания std::string может стоять много чего: char, char*, const std::string&, std::string&&, std::initializer_list.... Откуда можно узнать какая именно вам нужна?
И каждый день — без права на ошибку...
Re[5]: оператор приведения типа
От: rg45 СССР  
Дата: 28.01.19 13:15
Оценка:
Здравствуйте, collider, Вы писали:

C>Спасибо за ваш ответ и за предостережения, но мой вопрос изначально был несколько другим

C>Я так понимаю, нынешние компиляторы не способны выбрать нужную конкретизацию в такой ситуации и никакими ухищрениями типа SFINAE не поможешь.
C>Я правильно понимаю?

Ответить в точности на поставленыый тобой вопрос затруднительно, уже хотя бы потому, что на разных компиляторах, и разных реализациях STL результат компиляции твоего примера может быть разным. Так на gcc, например, ошибка компиляции возникает даже в том месте, которое у тебя помечено как "работает". И причин тому может быть целый список, на разбор которого просто жаль тратить время. Ибо единственно верную рекомендацию для этого случая уже дали: так лучше не делать.
--
Re[6]: оператор приведения типа
От: collider  
Дата: 28.01.19 14:34
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, collider, Вы писали:


C>>Спасибо за ваш ответ и за предостережения, но мой вопрос изначально был несколько другим

C>>Я так понимаю, нынешние компиляторы не способны выбрать нужную конкретизацию в такой ситуации и никакими ухищрениями типа SFINAE не поможешь.
C>>Я правильно понимаю?

BFE>Вы так пишите, что можно подумать, что человек может выбрать нужную вам конкретизацию. Справа от оператора присваивания std::string может стоять много чего: char, char*, const std::string&, std::string&&, std::initializer_list.... Откуда можно узнать какая именно вам нужна?


Ну да, человек может. Исходя из типа переменной слева, посмотрел есть ли такой оператор приведения и всего делов Понятно, что скорее всего правила приоритета поиска нет в таком случае.
std::string str=val; //тут даже компилятор находит, не то что человек.
long lval = val; // и тут находит
lval = val; // и тут
Re[6]: оператор приведения типа
От: collider  
Дата: 28.01.19 14:46
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, collider, Вы писали:


C>>Спасибо за ваш ответ и за предостережения, но мой вопрос изначально был несколько другим

C>>Я так понимаю, нынешние компиляторы не способны выбрать нужную конкретизацию в такой ситуации и никакими ухищрениями типа SFINAE не поможешь.
C>>Я правильно понимаю?

R>Ответить в точности на поставленыый тобой вопрос затруднительно, уже хотя бы потому, что на разных компиляторах, и разных реализациях STL результат компиляции твоего примера может быть разным. Так на gcc, например, ошибка компиляции возникает даже в том месте, которое у тебя помечено как "работает". И причин тому может быть целый список, на разбор которого просто жаль тратить время. Ибо единственно верную рекомендацию для этого случая уже дали: так лучше не делать.


Ясно, спасибо.

P.S.
Насчет std::any. Мне лично кажется недоделанным(мягко говоря) вариант, когда дают удобный в использовании operator=, а вот если обратно, то тут вам надо использовать any_cast, потому что мы не можем вам дать удобный инструмент ради вашей
же безопасности. И объяснение на несколько страниц. Это все равно что продавать авто, которое открывается и заводится с кнопки, если рядом находится ключ, а вот чтобы закрыть, надо провернуть ключ в замке двери. Ну и с объяснением почему так небезопасно.
Re[7]: оператор приведения типа
От: rg45 СССР  
Дата: 28.01.19 15:10
Оценка:
Здравствуйте, collider, Вы писали:

C>Насчет std::any. Мне лично кажется недоделанным(мягко говоря) вариант, когда дают удобный в использовании operator=, а вот если обратно, то тут вам надо использовать any_cast, потому что мы не можем вам дать удобный инструмент ради вашей

C>же безопасности. И объяснение на несколько страниц. Это все равно что продавать авто, которое открывается и заводится с кнопки, если рядом находится ключ, а вот чтобы закрыть, надо провернуть ключ в замке двери. Ну и с объяснением почему так небезопасно.

Это да, есть такое дело. И присваивание, и инициализация асимметричны по своей природе, по крайней мере в C++. И то, и другое слева обработать гораздо сподручнее, чем справа. В этом и корень "несправедливости".
--
Re[3]: оператор приведения типа
От: _NN_ www.nemerleweb.com
Дата: 28.01.19 19:07
Оценка:
Здравствуйте, collider, Вы писали:

C>Хотелось сделать более удобным в использовании(если можно привести то возвращаем, нет- exception),без использования cast-ов.


От неоднозначностей не убежишь в любом случае.

struct MyAny
{

    template<class V>
    operator V&()
    {
        return V();
    }
    template<class V>
    operator const V&() const
    {
        return V();
    }
};

struct Q
{
    Q(int=0){}
    Q(double=0){}
};


int main()
{
 MyAny myAny;
 Q q = myAny; // Что тут делать надо ? :)
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: оператор приведения типа
От: collider  
Дата: 28.01.19 19:53
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, collider, Вы писали:


C>>Хотелось сделать более удобным в использовании(если можно привести то возвращаем, нет- exception),без использования cast-ов.


_NN>От неоднозначностей не убежишь в любом случае.


_NN>
_NN>struct MyAny
_NN>{

_NN>    template<class V>
_NN>    operator V&()
_NN>    {
_NN>        return V();
_NN>    }
_NN>    template<class V>
_NN>    operator const V&() const
_NN>    {
_NN>        return V();
_NN>    }
_NN>};

_NN>struct Q
_NN>{
_NN>    Q(int=0){}
_NN>    Q(double=0){}
_NN>};


_NN>int main()
_NN>{
_NN> MyAny myAny;
_NN> Q q = myAny; // Что тут делать надо ? :)
_NN>}
_NN>

Спасибо, я уже понял. Хотя по мне, сначала ищи конструктор копирования, а уж ежели не окажется, тогда уж и высказывай свое негодование такими вот загадками
Re[5]: оператор приведения типа
От: _NN_ www.nemerleweb.com
Дата: 29.01.19 18:53
Оценка:
Здравствуйте, collider, Вы писали:

C>Спасибо, я уже понял. Хотя по мне, сначала ищи конструктор копирования, а уж ежели не окажется, тогда уж и высказывай свое негодование такими вот загадками

Я думаю можно через SFINAE что-нибудь наколдовать.
Только вам нужно формализировать, что должно работать и в каких случаях.
http://rsdn.nemerleweb.com
http://nemerleweb.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.