Здравствуйте, collider, Вы писали:
C>Что то типа std::any, но со своими нюансами. C>Хотелось сделать более удобным в использовании(если можно привести то возвращаем, нет- exception),без использования cast-ов.
Неявные преобразования — штука очень коварная, зачастую приносят вреда больше, чем пользы. Проблема неявных проразований много обсуждалась на протяжении многих лет. Как итог этих обсуждений можно рассматривать вот такое правило:
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 неявные преобразования не используются вовсе не потому, что авторы стандартной библиотеки не знают о существовании пользовательских операторов приведения типа
Здравствуйте, 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 не поможешь.
Я правильно понимаю?
Здравствуйте, collider, Вы писали:
C>Спасибо за ваш ответ и за предостережения, но мой вопрос изначально был несколько другим C>Я так понимаю, нынешние компиляторы не способны выбрать нужную конкретизацию в такой ситуации и никакими ухищрениями типа SFINAE не поможешь. C>Я правильно понимаю?
Вы так пишите, что можно подумать, что человек может выбрать нужную вам конкретизацию. Справа от оператора присваивания std::string может стоять много чего: char, char*, const std::string&, std::string&&, std::initializer_list.... Откуда можно узнать какая именно вам нужна?
Здравствуйте, collider, Вы писали:
C>Спасибо за ваш ответ и за предостережения, но мой вопрос изначально был несколько другим C>Я так понимаю, нынешние компиляторы не способны выбрать нужную конкретизацию в такой ситуации и никакими ухищрениями типа SFINAE не поможешь. C>Я правильно понимаю?
Ответить в точности на поставленыый тобой вопрос затруднительно, уже хотя бы потому, что на разных компиляторах, и разных реализациях STL результат компиляции твоего примера может быть разным. Так на gcc, например, ошибка компиляции возникает даже в том месте, которое у тебя помечено как "работает". И причин тому может быть целый список, на разбор которого просто жаль тратить время. Ибо единственно верную рекомендацию для этого случая уже дали: так лучше не делать.
Здравствуйте, 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; // и тут
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, collider, Вы писали:
C>>Спасибо за ваш ответ и за предостережения, но мой вопрос изначально был несколько другим C>>Я так понимаю, нынешние компиляторы не способны выбрать нужную конкретизацию в такой ситуации и никакими ухищрениями типа SFINAE не поможешь. C>>Я правильно понимаю?
R>Ответить в точности на поставленыый тобой вопрос затруднительно, уже хотя бы потому, что на разных компиляторах, и разных реализациях STL результат компиляции твоего примера может быть разным. Так на gcc, например, ошибка компиляции возникает даже в том месте, которое у тебя помечено как "работает". И причин тому может быть целый список, на разбор которого просто жаль тратить время. Ибо единственно верную рекомендацию для этого случая уже дали: так лучше не делать.
Ясно, спасибо.
P.S.
Насчет std::any. Мне лично кажется недоделанным(мягко говоря) вариант, когда дают удобный в использовании operator=, а вот если обратно, то тут вам надо использовать any_cast, потому что мы не можем вам дать удобный инструмент ради вашей
же безопасности. И объяснение на несколько страниц. Это все равно что продавать авто, которое открывается и заводится с кнопки, если рядом находится ключ, а вот чтобы закрыть, надо провернуть ключ в замке двери. Ну и с объяснением почему так небезопасно.
Здравствуйте, collider, Вы писали:
C>Насчет std::any. Мне лично кажется недоделанным(мягко говоря) вариант, когда дают удобный в использовании operator=, а вот если обратно, то тут вам надо использовать any_cast, потому что мы не можем вам дать удобный инструмент ради вашей C>же безопасности. И объяснение на несколько страниц. Это все равно что продавать авто, которое открывается и заводится с кнопки, если рядом находится ключ, а вот чтобы закрыть, надо провернуть ключ в замке двери. Ну и с объяснением почему так небезопасно.
Это да, есть такое дело. И присваивание, и инициализация асимметричны по своей природе, по крайней мере в C++. И то, и другое слева обработать гораздо сподручнее, чем справа. В этом и корень "несправедливости".
Здравствуйте, 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; // Что тут делать надо ? :)
}
Здравствуйте, _NN_, Вы писали:
_NN>Здравствуйте, collider, Вы писали:
C>>Хотелось сделать более удобным в использовании(если можно привести то возвращаем, нет- exception),без использования cast-ов.
_NN>От неоднозначностей не убежишь в любом случае.
_NN>
Спасибо, я уже понял. Хотя по мне, сначала ищи конструктор копирования, а уж ежели не окажется, тогда уж и высказывай свое негодование такими вот загадками
Здравствуйте, collider, Вы писали:
C>Спасибо, я уже понял. Хотя по мне, сначала ищи конструктор копирования, а уж ежели не окажется, тогда уж и высказывай свое негодование такими вот загадками
Я думаю можно через SFINAE что-нибудь наколдовать.
Только вам нужно формализировать, что должно работать и в каких случаях.