Писать typename Graph::vertex_descriptor тяжело и длинно.
Можно ли сказать так:
template <class Graph>
имей_в_виду_что vertex=typename Graph::vertex_descriptor
void fn(Graph &g, d1,typename Graph::edge_descriptor d2)
{...}
Понятно,что можно сделать ещё один параметр шаблона и задать его значением по умолчанию, но это как-то кажется некрасивым. Может есть ещё какой-то способ?
Здравствуйте, al.zatv, Вы писали:
AZ>Вот есть функция,параметризуемая шаблоном. Внутри этого шаблона есть длинный тип, который мне надо использовать. Например
AZ>template <class Graph> AZ>void fn(Graph &g, typename Graph::vertex_descriptor d1) AZ>{...}
AZ>Писать typename Graph::vertex_descriptor тяжело и длинно.
AZ>Можно ли сказать так: AZ>template <class Graph> AZ>имей_в_виду_что vertex=typename Graph::vertex_descriptor AZ>void fn(Graph &g, d1,typename Graph::edge_descriptor d2) AZ>{...}
AZ>Понятно,что можно сделать ещё один параметр шаблона и задать его значением по умолчанию, но это как-то кажется некрасивым. Может есть ещё какой-то способ?
AZ>Заранее благодарен
Здравствуйте, al.zatv, Вы писали:
AZ>Можно ли сказать так: AZ>template <class Graph> AZ>имей_в_виду_что vertex=typename Graph::vertex_descriptor AZ>void fn(Graph &g, d1,typename Graph::edge_descriptor d2) AZ>{...}
AZ>Понятно,что можно сделать ещё один параметр шаблона и задать его значением по умолчанию, но это как-то кажется некрасивым. Может есть ещё какой-то способ?
а если учесть что шаблонные параметра по умолчанию для функций не работают, совсем грустно становится.
нормального способа в текущем стандарте нет (про новый не знаю)
можешь сделать
template <class Graph, typename Vertex>
void fn(Graph &g, d1, Vertex d2)
AZ>Заранее благодарен
AZ>не,мопед не мой,лезть в него нельзя. там тем более десятки классов,которые под эту функцию подходят.
Что-то я не понял в чем проблема-то собственно говоря?? Если это не твои классы и изменять их нельзя, то какая тебе разница, какой длины там параметры в этих функциях?? Или в чем фишка-то??
Здравствуйте, ZegSoft, Вы писали:
ZS>Что-то я не понял в чем проблема-то собственно говоря?? Если это не твои классы и изменять их нельзя, то какая тебе разница, какой длины там параметры в этих функциях?? Или в чем фишка-то??
Класс не мой, а функция моя! И я хочу её записывать покороче.
Мне надо функцию описать
template <class Graph>
void fn(Graph &g, typename Graph::vertex_descriptor d1,typename Graph::vertex_descriptor d1, typename Graph::edge_descriptor e1,Graph::edge_descriptor e2)
{
и внутри постоянно использую vertex_descriptor
}
Очень длинно, почти нечитабельно. Я хочу укоротить
template <class Graph>
ЗАПОМНИТЬ_ЧТО vertex=typename Graph::vertex_descriptor И edge=typename Graph::vertex_descriptor
void fn(Graph &g, vertex d1,vertex d1, edge d1)
{
и внутри всё будет короче
}
Класс, который полезет под шаблон Graph, не мой. Так что поменять там внутри vertex_descriptor на vertex я не могу. Это вообще-то класс из Boost Graph Library, но это не важно.
Здравствуйте, night beast, Вы писали:
NB>а если учесть что шаблонные параметра по умолчанию для функций не работают, совсем грустно становится. NB>нормального способа в текущем стандарте нет (про новый не знаю) NB>можешь сделать NB>template <class Graph, typename Vertex> NB>void fn(Graph &g, d1, Vertex d2)
О, спасибо за ответ! И спасибо что вникли.
Я вообще-то сделал вот так:
template <class Graph, typename Vertex=typename Graph::vertex_descriptor>
void fn(Graph &g, d1, Vertex d2)
но мне это кажется некрасивым, так как граф может оказаться от одного класса, а вершина от другого.
Это — самое простое и очевидное решение твоей надуманной (как мне кажется) проблемы.
Если так уж хочется иметь короткий список параметров и тебе не нужна перегрузка по этим параметрам (т.е. у тебя всего одна функция), то можно так:
template <class Graph, class Vertex, class Edge>
void fn( Graph &g, Vertex d1, Vertex d2, Edge e1, Edge e2 )
{
BOOST_STATIC_ASSERT(( boost::is_same< Vertex, typename Graph::vertex_descriptor>::value ));
BOOST_STATIC_ASSERT(( boost::is_same< Edge, typename Graph::edge_descriptor>::value ));
//и внутри постоянно использую Vertex
}
Но лично мне решение в столбик нравится больше — оно проще и очевиднее.
В теле функции можно и typedef-ы завести (формально по текущему стандарту использовать typedef-объявление в определении функции нельзя, но, поскольку данное ограничение — очевидный идиотизм, я не встречал ни одного современного компилятора, который бы не допускал любые typedef-объявления в телах функций).
J>Если так уж хочется иметь короткий список параметров и тебе не нужна перегрузка по этим параметрам (т.е. у тебя всего одна функция), то можно так: J>
Тут ещё надо учитывать, что при автоматическом выведении типов Vertex, Edge и т.д. многим потенциально возможным неявным преобразованиям к Graph::vertex_descriptor и т.д. сразу будет красный свет. Неявные null pointer conversions будут недоступными даже при замене boost::is_same на boost::is_convertible.
J>Это — самое простое и очевидное решение твоей надуманной (как мне кажется) проблемы.
позволь не согласиться насчет надуманности.
проблема многословности существует, способствует копипасту, засоряет код.
добавь туда еще темплейт, совсем красиво будет:
еще не начали писать функцию, а уже заняли 7 строчек.
J>Если так уж хочется иметь короткий список параметров и тебе не нужна перегрузка по этим параметрам (т.е. у тебя всего одна функция), то можно так: J>
Здравствуйте, Masterkent, Вы писали:
M>(формально по текущему стандарту использовать typedef-объявление в определении функции нельзя, но, поскольку данное ограничение — очевидный идиотизм, я не встречал ни одного современного компилятора, который бы не допускал любые typedef-объявления в телах функций).
Ну это явная ошибка, наверняка они хотели запретить в объявлении, а не в определении (типа как запрещено объявлять классы, например).
M>Тут ещё надо учитывать, что при автоматическом выведении типов Vertex, Edge и т.д. многим потенциально возможным неявным преобразованиям к Graph::vertex_descriptor и т.д. сразу будет красный свет. Неявные null pointer conversions будут недоступными даже при замене boost::is_same на boost::is_convertible.
Здравствуйте, al.zatv, Вы писали:
NB>>а если учесть что шаблонные параметра по умолчанию для функций не работают, совсем грустно становится. NB>>нормального способа в текущем стандарте нет (про новый не знаю) NB>>можешь сделать NB>>template <class Graph, typename Vertex> NB>>void fn(Graph &g, d1, Vertex d2)
AZ>О, спасибо за ответ! И спасибо что вникли. AZ>Я вообще-то сделал вот так: AZ>template <class Graph, typename Vertex=typename Graph::vertex_descriptor> AZ>void fn(Graph &g, d1, Vertex d2)
AZ>но мне это кажется некрасивым, так как граф может оказаться от одного класса, а вершина от другого.
если нужны ограничения на Vertex, то их можно сделать, но неявного преобразования все равно не будет:
Здравствуйте, night beast, Вы писали:
NB>Здравствуйте, jazzer, Вы писали:
AZ>>>Очень длинно, почти нечитабельно. J>>А ты в столбик напиши, и сразу станет читабельно J>>Это — самое простое и очевидное решение твоей надуманной (как мне кажется) проблемы.
NB>позволь не согласиться насчет надуманности. NB>проблема многословности существует, способствует копипасту, засоряет код. NB>добавь туда еще темплейт, совсем красиво будет: NB>
NB>еще не начали писать функцию, а уже заняли 7 строчек.
Ну заняли — и ладно, если по-человечески отформатировано, то все вполне читабельно.
Конечно, лучше было бы менее многословно, но правильное форматирование очень помогает.
Язык у нас многословный, ничего не поделаешь
Тот же typename в абсолютном большинстве случаев не нужен, его нужно оставить только для реально двусмысленных случаев, когда и тип, и значение может быть. Т.е. в аргументах функции, очевидно, могут быть только типы — ну ни нафига требовать typename Тем более что, например, с базами typename не нужен. При этом typename вне шаблона не компилируется, в результате с макросами приходится делать две версии, одна для шаблонов, другая для обычных классов
Если так уж надо сокращать запись — надо юзать макросы, других вменяемых способов я не вижу.
Типа
J>>Но лично мне решение в столбик нравится больше — оно проще и очевиднее.
NB>здесь проблема в том, неявные преобразования не работают.
их можно выполнить внутри функции, где уже будет доступен typedef. NB>ну и возвращаемый тип таким образом не сделать.
в смысле — не сделать? Если это должен быть Vertex — так он так и останется. Если нет преобразований, конечно.
В любом случае, как я уже сказал, я реальной альтернативы столбику не вижу.
Здравствуйте, jazzer, Вы писали:
NB>>еще не начали писать функцию, а уже заняли 7 строчек. J>Ну заняли — и ладно, если по-человечески отформатировано, то все вполне читабельно. J>Конечно, лучше было бы менее многословно, но правильное форматирование очень помогает. J>
и это только объявление одного аргумента
J>Язык у нас многословный, ничего не поделаешь
я к тому что это не надуманная проблема. то что ничего не поделаешь, это да
J>>>Но лично мне решение в столбик нравится больше — оно проще и очевиднее.
NB>>ну и возвращаемый тип таким образом не сделать. J>в смысле — не сделать? Если это должен быть Vertex — так он так и останется. Если нет преобразований, конечно.
Здравствуйте, night beast, Вы писали:
NB>Здравствуйте, jazzer, Вы писали:
NB>>>еще не начали писать функцию, а уже заняли 7 строчек. J>>Ну заняли — и ладно, если по-человечески отформатировано, то все вполне читабельно. J>>Конечно, лучше было бы менее многословно, но правильное форматирование очень помогает. J>>
NB>и это только объявление одного аргумента
J>>Язык у нас многословный, ничего не поделаешь
NB>я к тому что это не надуманная проблема. то что ничего не поделаешь, это да
Ну, если этот крокодил повторяется и зависит только от графа, то его можно и в метафункцию упаковать, в результате получится нечто вроде
Здравствуйте, al.zatv, Вы писали:
AZ>Вот есть функция,параметризуемая шаблоном. Внутри этого шаблона есть длинный тип, который мне надо использовать. Например
AZ>template <class Graph> AZ>void fn(Graph &g, typename Graph::vertex_descriptor d1) AZ>{...}
AZ>Писать typename Graph::vertex_descriptor тяжело и длинно.
AZ>Можно ли сказать так: AZ>template <class Graph> AZ>имей_в_виду_что vertex=typename Graph::vertex_descriptor AZ>void fn(Graph &g, d1,typename Graph::edge_descriptor d2) AZ>{...}
AZ>Понятно,что можно сделать ещё один параметр шаблона и задать его значением по умолчанию, но это как-то кажется некрасивым. Может есть ещё какой-то способ?