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

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

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 » new

По ссылке не прокатит, т.к. будет создана временная переменная.
нет нет, я не так выразился,  я имею в виду - передавать ссылку
Код:
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
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines