T>Хочется, чтобы такой код тоже работал.
ИМХО, такое количество операторов преобразования — это плохой стиль. Отсюда и все эти неоднозначности. Может быть определить методы to_string(), to_double() и т.д.?
Здравствуйте, Trapper, Вы писали:
T>Я не понимаю, откуда вдруг возникла неоднозначность? Есть специально для std::string оператор преобразования. Оператор преобразования к bool хуже, т.к. для него подбирается operator=(char), а char и bool не одно и тоже. По идее должен был выбраться оператор преобразования к std::string.
Подобные выкрутасы являются большой gray area в C++. Их лучше не использовать, иначе проблемы с переносимостью гарантрованы.
T>Буду признателен за объяснения и/или помощь в том, как заставить компилиться этот код.
Лучше не надо заставлять. Лучше переделать так, чтобы было 100% однозначно. Выкинуть оператор bool, например.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Всем привет.
Есть такой код, который не компилиться на gcc 4.1 и на comeau (на студии VS 7.1 всё собирается замечательно):
#include <string>
struct test_struct
{
operator bool () {return false;}
operator std::string () {return"";}
};
int main ()
{
std::string s;
test_struct test;
s = test; // вот здесь возникает ошибка
}
comeau пишет следующее:
line 13: error: more than one operator "=" matches these operands:
function "std::basic_string<_CharT, _Traits,
_Alloc>::operator=(const std::basic_string<_CharT,
_Traits, _Alloc> &) [with _CharT=char,
_Traits=std::char_traits<char>,
_Alloc=std::allocator<char>]"
function "std::basic_string<_CharT, _Traits,
_Alloc>::operator=(_CharT) [with _CharT=char,
_Traits=std::char_traits<char>,
_Alloc=std::allocator<char>]"
operand types are: std::string = test_struct
Я не понимаю, откуда вдруг возникла неоднозначность? Есть специально для std::string оператор преобразования. Оператор преобразования к bool хуже, т.к. для него подбирается operator=(char), а char и bool не одно и тоже. По идее должен был выбраться оператор преобразования к std::string.
Буду признателен за объяснения и/или помощь в том, как заставить компилиться этот код.
Здравствуйте, Trapper, Вы писали:
T>Всем привет. T>Есть такой код, который не компилиться на gcc 4.1 и на comeau (на студии VS 7.1 всё собирается замечательно):
T>
T>#include <string>
T>struct test_struct
T>{
T> operator bool () {return false;}
T> operator std::string () {return"";}
T>};
T>int main ()
T>{
T> std::string s;
T> test_struct test;
T> s = test; // вот здесь возникает ошибка
T>}
T>
T>comeau пишет следующее:
T>line 13: error: more than one operator "=" matches these operands: T> function "std::basic_string<_CharT, _Traits, T> _Alloc>::operator=(const std::basic_string<_CharT, T> _Traits, _Alloc> &) [with _CharT=char, T> _Traits=std::char_traits<char>, T> _Alloc=std::allocator<char>]" T> function "std::basic_string<_CharT, _Traits, T> _Alloc>::operator=(_CharT) [with _CharT=char, T> _Traits=std::char_traits<char>, T> _Alloc=std::allocator<char>]" T> operand types are: std::string = test_struct
T>Я не понимаю, откуда вдруг возникла неоднозначность? Есть специально для std::string оператор преобразования. Оператор преобразования к bool хуже, т.к. для него подбирается operator=(char), а char и bool не одно и тоже. По идее должен был выбраться оператор преобразования к std::string.
T>Буду признателен за объяснения и/или помощь в том, как заставить компилиться этот код.
#include <string>
class Foo;
void f(char c)
{
std::cout << c << std::endl;
}
int main ()
{
bool b = false;
void (Foo::*fn_ptr)() = 0; // Указатель на метод класса
f(b);
f(fn_ptr); // Косяк!return 0;
}
Суть в том, что bool неявно конвертится в char, а вот указатель на метод — нет.
А>ИМХО, такое количество операторов преобразования — это плохой стиль. Отсюда и все эти неоднозначности.
это ужасный стиль имхо. побочные эффекты от неявных преобразований гарантированы.
если уж struct то значит все что внутри public и можно использовать напрямую.
MS>Подобные выкрутасы являются большой gray area в C++. Их лучше не использовать, иначе проблемы с переносимостью гарантрованы.
Да, как раз пришёл к такой же мысли.
T>>Буду признателен за объяснения и/или помощь в том, как заставить компилиться этот код.
MS>Лучше не надо заставлять. Лучше переделать так, чтобы было 100% однозначно. Выкинуть оператор bool, например.
Ну да, придётся идти окольными путями, хотя жаль конечно. Но всё равно
Здравствуйте, Awaken, Вы писали:
А>>ИМХО, такое количество операторов преобразования — это плохой стиль. Отсюда и все эти неоднозначности.
A>это ужасный стиль имхо. побочные эффекты от неявных преобразований гарантированы.
За исключением уже описанной проблемы всё остальное работает как надо. Насчёт ужасного стиля — может быть, но делаю я так нечасто и только в тех случаях, когда это приносит ощутимую пользу, как сейчас.
Просто если делать всё стандартно, через всякие GetDouble и тд, то я лишаюсь основных преимуществ вроде выведения типа и тд. А основная цель — получить максимально удобный для использования компонент.
A>если уж struct то значит все что внутри public и можно использовать напрямую.
Не первый год замужем , инкапсуляцию использую, просто это тестовый пример
...
T>Просто если делать всё стандартно, через всякие GetDouble и тд, то я лишаюсь основных преимуществ вроде выведения типа и тд. А основная цель — получить максимально удобный для использования компонент.
А я одобряю — только дума нужно оставить приведение к std::string, long и double как самые часто юзаемые. А если еще и [] переопределить можно деревья организовать — такая штука может быть полезна когда Composite Template реализуешь.
У нас похожая схема в двух вариантах используется, правда в .NET и с implicit — работает как в песне:
Здравствуйте, artiz, Вы писали:
A>Здравствуйте, Trapper, Вы писали:
A>...
T>>Просто если делать всё стандартно, через всякие GetDouble и тд, то я лишаюсь основных преимуществ вроде выведения типа и тд. А основная цель — получить максимально удобный для использования компонент.
A>А я одобряю — только дума нужно оставить приведение к std::string, long и double как самые часто юзаемые. А если еще и [] переопределить можно деревья организовать — такая штука может быть полезна когда Composite Template реализуешь. A>У нас похожая схема в двух вариантах используется, правда в .NET и с implicit — работает как в песне:
A>
A>output["title"] = new Packet();
A>output["title"]["Item"] = "Dialog Title";
A>output["title"]["FontStyle"] = 1;
A>
Забавно, у меня похожий случай, используется для чтения настроек — теперь выглядит приблизительно так:
int var = params["param1"] || 0; // operator || не обязателен и служит для указания дефолтового значения, когда param1 не указан в конфиге
Здравствуйте, Trapper, Вы писали:
T>А до этого было:
T>
T>int var;
T>params.Get("param1", var, 0);
T>
А мне как было больше нравится
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском