Re[8]: перегрузка и шаблон
От: Eternity Россия  
Дата: 14.09.13 09:57
Оценка:
Здравствуйте, wvoquine, Вы писали:

W>Вот тут как раз точно совпадают в отличие от того случая (где требовалось преобразование). И выходом из этого было при точном совпадении (а шаблон только такое и дает) сделать нешаблонные функции более приоритетными.


Окей, для выхода из сложившейся проблемы с перегрузкой производных типов, давай (внезапно) сделаем приоритет конкретного типа перед базовым.
Re[6]: перегрузка и шаблон
От: Eternity Россия  
Дата: 14.09.13 10:02
Оценка:
Здравствуйте, wvoquine, Вы писали:

W>В том то и дело, что она не принимает какой-то тип — какого-то типа не существует. Шаблон функции — это, говоря языком формальной логики, схема функций, и аргументы у него схематичны. То есть нет этого какого-то аргумента, а есть схемы, в которые мы можем подставить какие-то аргументы, и схема инстанцируется в нечто конкретное, с конкретным типом аргумента. То есть для каждого подставленного типа аргумента генерируется отдельная функция, и это не просто деталь реализации, это и есть схема по своему смыслу.

W>Потому и получается точное совпадение — с инстанцированной по типу схемой.

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

#include <iostream>

using namespace std;

class A {};

void f(const A& a) {
    cout << "f(A);" << endl;
}

template <class T>
void f(const T& t) {
    cout << "f(T);" << endl;
}

int main() {
    A a;
    f(a);
    return 0;
}
Re[9]: перегрузка и шаблон
От: wvoquine  
Дата: 14.09.13 10:11
Оценка:
Здравствуйте, Eternity, Вы писали:

E>Здравствуйте, wvoquine, Вы писали:


W>>Вот тут как раз точно совпадают в отличие от того случая (где требовалось преобразование). И выходом из этого было при точном совпадении (а шаблон только такое и дает) сделать нешаблонные функции более приоритетными.


E>Окей, для выхода из сложившейся проблемы с перегрузкой производных типов, давай (внезапно) сделаем приоритет конкретного типа перед базовым.



Не надо, производный тип в том случае более специфичен, а потому он и выбирается.

А в этом случае нет более специфичной в смысле отношение базового и производного классов.
Но есть специфичность в том смысле, что программист все-таки написал код для одной из них специально.
void f(const A& a) {  }
void f(const A& a) {  } // albeit generated from a template


А вот тот пример, что я раньше привел, где конструктор копирования неявно генерируется компилятором — вот тот момент получается немного кривым. Но к этому приводит логика языка.
To be is to be the value of a variable
Re[10]: перегрузка и шаблон
От: Eternity Россия  
Дата: 14.09.13 10:12
Оценка: 2 (1)
Здравствуйте, wvoquine, Вы писали:

Я пас. Ты победил в споре.
Re[7]: перегрузка и шаблон
От: wvoquine  
Дата: 14.09.13 10:17
Оценка:
С одной стороны, это как будто произвольный выбор, который всё-таки следует идеологии специфичности в некотором смысле.

Да, в каком-то смысле шаблон менее специфичем, чем функция с точным совпадением типа аргумента. Но это не мешает ему быть более специфичным, чем функция с типом, который точно не совпадает
To be is to be the value of a variable
Re[3]: Как вы думаете, является ли данное поведение перегрузки дебильным?
От: Кодт Россия  
Дата: 14.09.13 10:18
Оценка: 2 (1) :)
Здравствуйте, Kubyshev Andrey, Вы писали:

KA>Кодт.. скажи чесно, сколько у вас на работе человек которые так вот пишут ?


За всех не скажу, но из того, что я видел, — никто. Включая меня, потому что я придерживаюсь принципа КПСС (как можно проще сделать старайся).
Всякая компиляторная магия имеет свою цену:
— сложность осмысления (и объяснения коллегам — на комментировании разориться можно же!)
— время компиляции
— багоопасные нюансы
— морока при отладке

Поэтому такие опыты
— или очень компактные, — в пределах одного метода, или одного .cpp, или, максимум, в пределах одного неймспейса my_utility_aux
— или write-only/once (use-everywhere) код, такой как буст (я к бусту непричастен — а жаль?)
— или как ответная часть к магическим библиотекам (к бусту)

Но уметь это дело — я умею. Just for fun
Перекуём баги на фичи!
Re[8]: перегрузка и шаблон
От: Eternity Россия  
Дата: 14.09.13 10:22
Оценка:
Здравствуйте, wvoquine, Вы писали:

W>Да, в каком-то смысле шаблон менее специфичем, чем функция с точным совпадением типа аргумента. Но это не мешает ему быть более специфичным, чем функция с типом, который точно не совпадает


В СССР все люди равны, но некоторые равнее других.
Re[11]: перегрузка и шаблон
От: wvoquine  
Дата: 14.09.13 10:27
Оценка:
Здравствуйте, Eternity, Вы писали:

E>Здравствуйте, wvoquine, Вы писали:


E>Я пас. Ты победил в споре.



И все-таки остается пример с неявно сгенеренным конструктором копирования, у которого больший приоритет, чем у шаблона, добавленного программистом специально. Тебе он должен понравиться
To be is to be the value of a variable
Re[3]: Как вы думаете, является ли данное поведение перегрузки дебильным?
От: jazzer Россия Skype: enerjazzer
Дата: 14.09.13 10:41
Оценка:
Здравствуйте, Eternity, Вы писали:

E>Вообще-то нет, я спросил именно о дизайне языка, так как собираюсь ради самообразования разработать очередной диалект C++.


В таком случае я предложил бы сначала вдумчиво прочитать Стандарт.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: Как вы думаете, является ли данное поведение перегрузки дебильным?
От: Кодт Россия  
Дата: 14.09.13 10:47
Оценка: 2 (1)
Здравствуйте, Eternity, Вы писали:

E>Вообще-то нет, я спросил именно о дизайне языка, так как собираюсь ради самообразования разработать очередной диалект C++. То, что решить можно, понятно. На практике можно просто перегрузки делать через enable_if. Меня интересует вопрос идеологии.


Про идеологию — лучше стоит подумать вот о чём.

Для компилятора контекст, в котором он принимает решения, состоит из куска единицы компиляции от начала файла до текущей точки.
Либо от начала файла до конца самого внешнего определяемого класса.
Либо (этим отличается VC) до точки первого воплощения шаблона.

Поэтому код становится крайне чувствительным к порядку объявления.

В принципе, проблему можно было бы решить двухпроходным компилятором, который за один раз собирает все объявления, а за второй раз — делает все уточнения даже этих объявлений.
Но я не уверен, решается ли проблема целиком. И не вылезают ли при этом какие-то другие грабли.



А что касается шаблонов, — ну да, есть такое дело: в случае неоднозначности или неудобной однозначности выбора сигнатур приходится искусственно выкручиваться, чтобы отдать предпочтение. Но это и нешаблонного кода касается. Рассмотрим простейший мультиметод времени компиляции.
voif f(ARoot*, BRoot*);
void f(ARoot*, BDerived*);
void f(ADerived*, BRoot*);

void g(ADerived* a, BDerived* b) { f(a,b); } // кого звать?

Если бы можно было расставить компилятору приоритеты — то выбор между второй и третьей сигнатурами был бы решён.
Ну а раз мы научимся расставлять приоритеты хотя бы атрибутом на уровне сигнатур, то, точно так же, сможем расставлять приоритеты и на уровне аргументов функции.
void f(ARoot*);
void f(ADerived1*);
template<class T> void f(T*) ATTR_PRIORITY(LOW); // LOWEST - это как (...), LOW - чуть выше, если ничего другое не подошло
template<class T> void f(T ATTR_PRIORITY(LOW)*);
void f(AnotherRoot* ATTR_CONVERSION(DISABLED)*); // только AnotherRoot, но не наследники


Впрочем, возможно, что борьба с компилятором — это неправильное место приложения усилий. Если встречаются какие-то такие места, где надо бороться, — то возможно, что стоит умерить гордыню и написать на Старом Добром Си, с уникальными именами, с отсутствием и перегрузки, и наследования...
Перекуём баги на фичи!
Re[4]: Как вы думаете, является ли данное поведение перегрузки дебильным?
От: Eternity Россия  
Дата: 14.09.13 10:50
Оценка:
Здравствуйте, jazzer, Вы писали:

E>>Вообще-то нет, я спросил именно о дизайне языка, так как собираюсь ради самообразования разработать очередной диалект C++.


J>В таком случае я предложил бы сначала вдумчиво прочитать Стандарт.


Чукча не читатель, чукча писатель. Мне кажется, что стандарт (с маленькой буквы) языка — это как help у программы. Если без хелпа программой пользоваться невозможно, интерфейс этой программы — говно.

Хотя, в целом, конечно, знать стандарт безусловно необходимо. Ты совершенно прав, хотя и совет твой очевиден, и, в общем-то, я нигде не говорил, что не собираюсь этого делать и не делал раньше, так что, в общем-то, совет очевидно бесполезен и дан с целью поддеть собеседника, слегка его оскорбить. Но из нас двоих это же я упертый, самолюбивый и агрессивный, так что неправ, очевидно я. Так что спасибо за совет.
Re[5]: Как вы думаете, является ли данное поведение перегрузки дебильным?
От: jazzer Россия Skype: enerjazzer
Дата: 14.09.13 11:00
Оценка:
Здравствуйте, Eternity, Вы писали:

E>Здравствуйте, jazzer, Вы писали:


E>>>Вообще-то нет, я спросил именно о дизайне языка, так как собираюсь ради самообразования разработать очередной диалект C++.


J>>В таком случае я предложил бы сначала вдумчиво прочитать Стандарт.


E>...совет очевидно бесполезен и дан с целью поддеть собеседника, слегка его оскорбить.


Не надо так остро воспринимать мои слова
Это совет из собственного опыта, я тоже писал сишный фронт-энд в свое время. И стандарт (тогда это был ARM) мне очень помог (сложно переоценить, я бы даже сказал) и именно его чтение дало мне понимание "нутра" С++ (справедливости ради, рулез ARM был отчасти и в буковке А).
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[9]: перегрузка и шаблон
От: wvoquine  
Дата: 14.09.13 11:27
Оценка:
Здравствуйте, Eternity, Вы писали:

E>В СССР все люди равны, но некоторые равнее других.




Кстати, в тех рассуждениях я никак не учел, что программист может и шаблон специализировать. То есть специально код написать для конкретного типа. Но выберется все равно (если такая есть) нешаблонная функция с точным совпадением (а в случае с неявным конструктором — этот неявный конструктор).

То есть более специфичный шаблон побьет менее специфичный, но их всех побьет точное совпадение по функции, если даже это конструктор, который не писал программист
To be is to be the value of a variable
Re[4]: Как вы думаете, является ли данное поведение перегрузки дебильным?
От: Don Reba Канада https://stackoverflow.com/users/49329/don-reba
Дата: 14.09.13 21:31
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Ну вот у нас все так пишут Других не берем


Не придерживаетесь вы принципа КПСС.
Ce n'est que pour vous dire ce que je vous dis.
Re[2]: Как вы думаете, является ли данное поведение перегрузки дебильным?
От: The Passenger Голландия  
Дата: 14.09.13 22:14
Оценка:
Здравствуйте, Кодт, Вы писали:

К>

К>template<class T> auto h(T const& x, int) -> decltype(g(x)) { g(x); }
К>template<class T> auto h(T const& x, ...) -> void           { g_default(x); }
К>


а можно хотябы вкратце раскурить эти пару строк

спасибо
Весь мир — Кремль, а люди в нем — агенты
Re[3]: Как вы думаете, является ли данное поведение перегрузки дебильным?
От: jazzer Россия Skype: enerjazzer
Дата: 15.09.13 03:28
Оценка: 4 (1) +1
Здравствуйте, The Passenger, Вы писали:
К>>
К>>template<class T> auto h(T const& x, int) -> decltype(g(x)) { g(x); }
К>>template<class T> auto h(T const& x, ...) -> void           { g_default(x); }
К>>


TP>а можно хотя бы вкратце раскурить эти пару строк


1. многоточие имеет наименьший приоритет при разрешении перегрузки.
2. SFINAE: ошибка при генерации сигнатуры шаблонной функции в процессе разрешения перегрузки не является ошибкой, просто такая функция будет выброшена из рассмотрения (иначе было бы невозможно работать с шаблонными функциями (и особенно операторами) — обязательно находилась бы какая-нть, которая не срастается с данным типом).

В нашем случае это означает, что если с g(x) какие-то проблемы (g(x) непосредственно участвует в сигнатуре — это ключевой момент), то первая перегрузка просто будет выброшена из рассмотрения и сработает вторая (которая подходит всегда — посмотри на ее сигнатуру). А если с g(x) все нормально — то сработает первая, так как вторая проиграет из-за многоточия.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[5]: Как вы думаете, является ли данное поведение перегрузки дебильным?
От: jazzer Россия Skype: enerjazzer
Дата: 15.09.13 03:29
Оценка:
Здравствуйте, Don Reba, Вы писали:

DR>Здравствуйте, jazzer, Вы писали:


J>>Ну вот у нас все так пишут Других не берем


DR>Не придерживаетесь вы принципа КПСС.


Да, мы придерживаемся принципа Эйнштейна: "Пусть это будет просто насколько возможно, но не проще"
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Вывод
От: Eternity Россия  
Дата: 15.09.13 08:02
Оценка:
Я сделал вывод, что в целом здесь проблема в смешивании номинативной и утиной типизации, которое делает логику выбора перегруженного метода двусмысленной в зависимости от того, с точки зрения какой типизации вы на нее посмотрите.

C++ отдает приоритет утиной типизации, но если бы в C++ было сделано так, как я описал, это было бы двусмысленно и неожиданно уже с другой точки зрения.

В общем, не надо смешивать утиную и номинативную типизацию, по крайней мере, без четкого указания как именно они разделяются.
Re[2]: Вывод
От: Кодт Россия  
Дата: 16.09.13 14:52
Оценка:
Здравствуйте, Eternity, Вы писали:

E>C++ отдает приоритет утиной типизации, но если бы в C++ было сделано так, как я описал, это было бы двусмысленно и неожиданно уже с другой точки зрения.


С чего это утиная?
Так можно и хаскелл с МЛами назвать утино-типизированными языками, потому что там сопоставление по образцу происходит: если выглядит как утка...
Перекуём баги на фичи!
Re[3]: Вывод
От: Eternity Россия  
Дата: 17.09.13 06:25
Оценка:
Здравствуйте, Кодт, Вы писали:

К>С чего это утиная?


А какая у шаблонов в C++ типизация?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.