Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Двойное преобразование пользовательских типов c++


Автор: vardan 22.5.2013, 16:35
В правиле 5 книги С. Майерса " Наиболее эффективное использование C++. 35 новых рекомендаций" приводится пример преобразования типов. Там говорится что "Ранее я упоминал, что правила, по которым определяется, какие последовательности неявного преобразования типа корректны, а какие нет, довольно сложны. Одно из этих правил состоит в том, что последовательность преобразований не может содержать более одного преобразования, определенного пользователем (то есть вызова конструктора с единственным аргументом или оператора неявного преобразования типа)."
Есть класс класс Array и встроенный класс ArraySize
Код

template <class T>
class Array
{
public:
class ArraySize
{
public:
ArraySize(int numElements):theSize(numElements){}
int size() const;
private:
int theSize;
};
Array(int lowBound, int highBound);
Array(ArraySize size);
...
};

 и создается объект таким образом
Код

Array<int>a(10); 
 
в книге говорится что в этом случае компилятор преобразует аргумент типа int во временный объект ArraySize поскольку  ArraySize именно то что нужно Array<int>. Но во время вот этой операции
Код

bool operator==(const Array<int>& lhs, const Array<int>& rhs)
{
Array<int> a(10);
Array<int> b(10);
...
for(int i= 0; i < 10; ++i)
if(a == b[i])

говорится что компилятор не может преобразовать во временный объект ArraySize а затем создать необходимый объект Array<int> из временного потому что это потребует вызова двух преобразований определенных пользователем: из int в ArraySize и из ArraySize в Array<int>. Такая последовательность преобразований запрещена, поэтому при попытке выполнить сравнение компиляторы сгенерируют ошибку.
Вопрос в том чем отличается случай с Array<int>a(10); когда преобразование успешно выполняется от случая в теле операторa operator==(const Array<int>& lhs, const Array<int>& rhs) когда компилятор не выполняет преобразование. В обоих случаях та же схема из int -а в ArraySize и из ArraySize в Array<int>. Спасибо

Автор: Result 22.5.2013, 22:50
Как вариант потому, что автоматическое выведение типа шаблонного параметра из входного аргумента работает только для функций. 

Хотя нет, в первом случае одно приведение из int в ArraySize, т.е. 
Цитата

и из ArraySize в Array<int>

не выполняется.

Первый случай
Код

Array::ArraySize tmp(10);//забыл как обращаться к локальным классам :(
Array<int> a(tmp);


Во втором случае не пойму когда происходит первое-второе преобразование при передаче по ссылке. 

Автор: volatile 22.5.2013, 23:57
Цитата(vardan @  22.5.2013,  16:35 Найти цитируемый пост)
Вопрос в том чем отличается случай с Array<int>a(10); когда преобразование успешно выполняется от случая в теле операторa operator==(const Array<int>& lhs, const Array<int>& rhs) когда компилятор не выполняет преобразование.

Ничем не отличаецца. скорей всего ошибка где-то в другой строке, например здесь.
Цитата(vardan @  22.5.2013,  16:35 Найти цитируемый пост)
if(a == b[i])


Либо вы не корректно привели отрывок кода. (по крайней мере, смысла внутри оператор== , я пока не вижу что-то...)

Автор: volatile 23.5.2013, 00:14
Цитата(volatile @  22.5.2013,  23:57 Найти цитируемый пост)
ошибка где-то в другой строке, например здесь.
if(a == b[i])


Если вы эту строку и имели ввиду, и именно это вы и хотели, то да, так не будет работать.
нужно писать, например.
bool operator==(const Array<int>& lhs, int)
{...


Автор: NoviceF 23.5.2013, 19:03
Цитата(volatile @  23.5.2013,  01:14 Найти цитируемый пост)
Если вы эту строку и имели ввиду, и именно это вы и хотели, то да, так не будет работать.


Уж не знаю, что хотел сказать автор, но Мэйерс говорит явно не об этом smile

Код

if(a == b[i])

В этом примере, программист как бы забыл указать индекс у массива а (хотел сравнить массивы поэлементно), и в этом случае, если Array имеет конструктор, позволяющий неявные преобразования, он будет вызван для значения инт, которым является b[i]; 

Кстати, непонимание автора, видимо, вызвано вот этой деталью (в моём варианте книге так):

Код

bool operator==(const Array<int>& lhs, const Array<int>& rhs); //это есть
{ //этого нет
Array<int> a(10);
Array<int> b(10);
...
for(int i= 0; i < 10; ++i)
if(a == b[i])



Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)