Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 [Все]   Вниз
  Печать  
Автор Тема: неявные приведения типов  (Прочитано 32431 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« : 31-08-2010 07:38 » 

Вопрос такой: тип параметров некой функции может со временем поменяться, поэтому: как указать компилятору, чтобы он не делал неявных приведений типов аргументов при вызове этой функции, то есть чтобы ругань происходила даже если пытаемся переменную типа short  передать в агрумент типа int ?

По всему коду это не требуется, а только для  конкретной одной функции, для контроля
Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 31-08-2010 09:02 » 

В голову приходит только шаблонная функция, инстанцированная только для типа int, например.
Как-то так:
Код:
template <typename Type>
Type foo(Type);

int foo(int val)
{
    return 2 * val;
}

int main()
{
    const int c = 1;
    int x = foo(c);     // OK, use int foo(int)
    const short c2 = 2;
    int x2 = foo(c2);   // error LNK2001: unresolved external symbol "short __cdecl foo<short>(short)" (??$foo@F@@YAFF@Z)

    return 0;
}
Наверное, можно этот подход улучшить, чтобы сообщение об ошибке было более чётким, а не на этапе линковки.

У конструкторов ещё есть  explicit.
« Последнее редактирование: 31-08-2010 09:06 от Вад » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #2 : 31-08-2010 09:46 » 

так, а если значения по ссылке передавать - прокатит ? Даже без шаблона ведь должно?

explicit - это как
Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 31-08-2010 11:31 » 

По ссылке не прокатит, т.к. будет создана временная переменная.

С шаблоном прокатывает только потому, что при поиске наилучшего соответствия шаблон будет лучше подходить, его-то компилятор и подставит, не заботясь о том, инстанцирован ли он.

explicit - это указание компилятору, что конструктор может использоваться только явно:
Код:
class boo
{
    int m_;
public:
    boo(int m) : m_(m) {
        std::cout << "boo(int)" << std::endl;
    }
};

class ddd
{
    int m_;
public:
    explicit ddd(int m) : m_(m) {
        std::cout << "ddd(int)" << std::endl;
    }
};

int main()
{
    boo x1 = boo(1); // OK, "boo(int)"
    boo x2 = 1;      // OK, "boo(int)"
    ddd y1 = ddd(1); // OK, "ddd(int)"
    ddd y2 = 1;      // error C2440: 'initializing' : cannot convert from 'int' to 'ddd'
    return 0;
}

explicit хорошо помогает, если мы не хотим, чтобы к нашему классу происходило неявное преобразование, например, при передаче того же int в функцию, где аргументом выступает ddd.
« Последнее редактирование: 31-08-2010 11:32 от Вад » Записан
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #4 : 31-08-2010 12:03 » 

я бы сказал, что в данном случае надо просто обернуть параметы функции классом (можно даже с паблик членами) у которого сделать explicit конструктор или даже для читаемости сделал бы просто проверку, ну примерно так

Код:
class checkParam
{
public:
    explicit checkParam(int _m, char _p) {}
};

void f(int m, char p)
{
    checkParam(m, p);

    // do what you need
}
Записан

С уважением Lapulya
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #5 : 31-08-2010 12:59 » 

мне кажется в новом стандарте были какие-то поползновения на это счёт
Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 31-08-2010 13:34 » 

По ссылке не прокатит, т.к. будет создана временная переменная.
нет нет, я не так выразился,  я имею в виду - передавать ссылку
Код:
void F(type& t1)
{
}
я точно не могу сказать, но вроде всегда в таких случаях компилятор резво реагирует, даже если различие только в модификаторе const
Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 31-08-2010 13:59 » 

Ну что я могу сказать... попробуй Ага Но я всё именно так и понял
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #8 : 01-09-2010 04:30 » 

нет нет, я не так выразился,  я имею в виду - передавать ссылку
Код:
void F(type& t1)
{
}
я точно не могу сказать, но вроде всегда в таких случаях компилятор резво реагирует, даже если различие только в модификаторе const

что-то я не понял в чём фишка

Я в своё время делал реализацию енумов которые нельзя было явно приводить к другим типам (задрало меня, что народ енумы в инты превращает, а по коду разбросаны магические числа), ну так вот я слела шаблонный класс обёртку который вел себя, как енум до тех пор пока его не пытались приводить в инт или другой енум (бывали случаи). Далее я в функции/методы передавал/возвращал только этот тип, какое-то время убил, что бы найти все места, где было некорретное использование (компиляцию яное дело разорвало, ну я к этому и стремился)
вот как-то так
« Последнее редактирование: 01-09-2010 04:51 от Антон (LogRus) » Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 01-09-2010 04:46 » 

да, с const я не то сказал. А вот с типами вроде нормально:

Код:
void Fi(int& t)
{
}

void Fc(char& t)
{
}

int i=0;
char c=0;
Fi(i);
Fi(c);//error
Fc(i);//error
Fc(c);
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #10 : 01-09-2010 04:52 » 

я предыдущий пост дополнил
Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 01-09-2010 05:02 » 

так я ж не про енумы, я про типы аргументов функций Улыбаюсь
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #12 : 01-09-2010 05:14 » 

ну это как концепция
Записан

Странно всё это....
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 01-09-2010 08:29 » 

да, с const я не то сказал. А вот с типами вроде нормально
Но тогда нарушается другое: ты уже не можешь передавать в функцию константные данные. Если у тебя аргумент не изменяется, а является лишь исходными данными, это тоже не слишком хорошо.

Можно, конечно, пойти дальше, и требовать передавать константный указатель на int... Улыбаюсь
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #14 : 01-09-2010 08:37 » 

ты уже не можешь передавать в функцию константные данные
да, но, предположим, обеспечим, что везде будут передаваться объекты, а не константы Улыбаюсь А оптимизация потом сделает своё белое дело (наверное). Зато, цель достигнута
Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 01-09-2010 09:09 » 

ты уже не можешь передавать в функцию константные данные
да, но, предположим, обеспечим, что везде будут передаваться объекты, а не константы Улыбаюсь А оптимизация потом сделает своё белое дело (наверное). Зато, цель достигнута
А константные объекты - это уже не объекты? Улыбаюсь По-моему, если что-то в функции не меняется, то оно по возможности и должно описываться как const (особенно ссылочные типы) - дабы более чётко декларировать свои намерения. Равно как описание методов класса как константных, если они не намереваются менять внутреннее состояние объекта. Чтобы неповадно было.
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #16 : 01-09-2010 16:29 » 

я бы всё таки поместил всё в прокси объекты и передавал бы прокси объекты
это будет железно работать
Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #17 : 01-09-2010 16:40 » 

прокси объекты - это шо за зверь такой ? )
Записан

lapulya
Молодой специалист

ru
Offline Offline

« Ответ #18 : 01-09-2010 21:18 » 

это, например, то, что я написал в самом начале)))))))))))))))
Записан

С уважением Lapulya
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #19 : 02-09-2010 03:58 » 

lapulya, вернее - в самом середИне Улыбаюсь
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #20 : 02-09-2010 04:31 » 

lapulya, это совсем не то
вот то:
Код:
template <typename T> class DataHolder;
typedef DataHolder<int> DHint;
typedef DataHolder<int> DHshort;
.......
DHint a;
DHshort b;
int aa;
short bb;
a = aa; //ok
aa = a; //ok
a = bb; //err
bb = a; //err

void foo(DHint a, DHshort b);

т.е. в функцию можно передать только те типы, которые позволит твой проси объект, при этом run-time оверхед будет практически нулевой, т.к. почти всё, если не всё, будет посчитано в compile-time
« Последнее редактирование: 03-09-2010 07:51 от Sel » Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #21 : 02-09-2010 04:47 » 

не пойму - а почему без тела класса , так можно что ли ?
template <typename T> class DataHolder;

то есть, по сути, тогда
DataHolder<int> - эквивалентен int , плюс невозможно неявное приведение
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #22 : 02-09-2010 08:28 » 

не пойму - а почему без тела класса , так можно что ли ?
template <typename T> class DataHolder;

то есть, по сути, тогда
DataHolder<int> - эквивалентен int , плюс невозможно неявное приведение

чтобы ты сам реализовал Улыбаюсь
« Последнее редактирование: 03-09-2010 07:51 от Sel » Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #23 : 02-09-2010 08:59 » 

ясно ) Я просто подумал, что тут что-то неизвестное произошло, вот и спросил ))
Записан

lapulya
Молодой специалист

ru
Offline Offline

« Ответ #24 : 02-09-2010 11:08 » 

Антон (LogRus),
можно как ты предложил, а можно и как я. Оборачиваем проверку в ifdef и в release версию это не входит, тогда вообще ничего лишнего выполняться не будет
Записан

С уважением Lapulya
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #25 : 03-09-2010 03:19 » 

lapulya, твоё решение не требует ifdef, в любом случае компилятор выкинет эту строчку.
что касается debug/release, то это вообще не аргумент Улыбаюсь кто сказал что дебаг версию хоть кто-то будет собирать Улыбаюсь
я их собираю только в случае, если найдена ошибка и много моих знакомых тоже.
на старой работе дебаг версия вообще не собирался Улыбаюсь в принцепе - какие-то ошибки из буста лезли, исправлять было некогда
Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #26 : 03-09-2010 05:03 » 

а я наоборот всегда в дебаге делаю, студия много ошибок подсказывает Улыбаюсь

(на обкатку пользователям делаю релиз, конечно )) )
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #27 : 03-09-2010 06:45 » 

ну это ты один, а когда у тебя разработчиков 200 не необходимый комплект тестовых бинарников в релизе собирается час а в дебаге и того больше при этом весит пару гигов вместе с отладочной инфой, то тут встаёт вопрос: "А оно мне надо?"

в общем в итоге моё мнение Улыбаюсь : если защита от дурака не несёт рантайм-оверхеда в релизе, то незачем её отключать
Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #28 : 03-09-2010 07:18 » 

если есть экономия времени - то да, я бы тоже в релизе только сидел, но ведь одинаково по времени. Хотя, я не замерял точно
Записан

lapulya
Молодой специалист

ru
Offline Offline

« Ответ #29 : 05-09-2010 20:19 » 

))) это ребилд олл занимает столько много времени, а билд намнооооого меньше, дай бог пару минут. Если дольше, то скорее всего слишком много ненужных инклудов в хеадерах.
Записан

С уважением Lapulya
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #30 : 05-09-2010 20:26 » 

))) это ребилд олл занимает столько много времени, а билд намнооооого меньше, дай бог пару минут. Если дольше, то скорее всего слишком много ненужных инклудов в хеадерах.
или много шаблонов. Что в случае Антона волне возможно Улыбаюсь
Записан
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #31 : 06-09-2010 16:53 » 

ну все равно чтобы сборка шла так долго, туча хеадеров (которые инклюдятся) должно измениться, очень слабо мне в это верится. Причем большая часть этих изменившихся хеадеров должны быть на низком уровне архитектуры (т.е. на них должно опираться много других, в противном случае он них мало что завист), а это еще больше сомнительно...
Записан

С уважением Lapulya
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #32 : 06-09-2010 18:55 » 

Много-много-много шаблонов, pdb файл одной из библиотек (парсер файлов, весь из себя шаблонный для ускорения парсинга) 800 мег, собирается 20 минут
ну это так специфика реализации
я почти всегда стараюсь делать ребилд всего перед коммитом, студия не всегда видела зависимости между файлами и грабли бывали в не предсказуемых местах, слишком сильно связанный код местами.
Записан

Странно всё это....
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #33 : 07-09-2010 23:01 » 

Во наплодили то...

Цитата
я почти всегда стараюсь делать ребилд всего перед коммитом... слишком сильно связанный код местами.

вот я об этом и говорил. Хотя подтвержу, ребилд иногда (редко правда) помогал, поскольку после некоторых обычных сборок была жопа.

А чего вы подобные ребилды не делаете на отдельной машине, так оно никому не мешает... и время не жрет... ну это я так мысли в слух... можно даже повесить скрипт на VCS по простановке метки с новой мажорной (ну или как надо) составляющей запускался ребилд, с выкладкой результатов на шару (или тоже в VCS), а потом можно и тесты запустить... )))
Записан

С уважением Lapulya
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #34 : 08-09-2010 06:37 » 

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

Вообще мы одно время пользовались (уже на старой работе Улыбаюсь к слову сказать) утилитой IncrediBuild она очень сильно ускоряла процесс сборки, но потом кончился триал, а денег на нормальную версию не выделили (точнее я ушел когда процесс был в стадии согласования)
Рекомендую утилиту, можно поставить её на мощные серваки для разгрузки машин разработки
Суть: выявить зависимости исходников, разослать на разные машины исходный код для сборки, потом на локальной машине всё скомпоновать
Это дело интегрируется в IDE
есть схожее решение для Linux/unix и бесплатное
Записан

Странно всё это....
Страниц: 1 2 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines