Сообщение Re[18]: Стадия компиляции от 07.01.2017 14:18
Изменено 07.01.2017 14:20 vdimas
Re[18]: Стадия компиляции
Здравствуйте, Qbit86, Вы писали:
Q>Стадия компиляции не выявит ошибку даже в пользовательском коде, если у пользователя есть свой метод `baz()`, вызова которого из библиотечного кода он не ожидает. Ведь он ожидает, что согласно документации будет вызываться `bar()`.
Ошибки перегрузки ловятся тестами, а не компилятором, ваш КО.
Такая же ошибка могла быть и не в шаблонном коде, если у целевого Т есть некий baz, помимо bar. Без тестирования ф-ии foo эти рассуждения ни о чем.
V>>Более того, в С++ легко проверить наличие нужного метода/методов даже в декларативном стиле уже имеющимися ср-вами языка (т.е. ср-в языка достаточно для разработки библиотечных приблуд требуемой функциональности).
Q>Это ты не мне расскажи, а Страуструпу. А то он не в курсе, что концепты не нужны: http://www.stroustrup.com/good_concepts.pdf
1. Я не против любых будущих улучшений языка С++, которые не будут нарушать его строгость и последовательность.
2. Речь шла о том, что многое можно делать уже сейчас.
3. Концепт не спасёт от ошибки перегрузки в твоём примере насчет bar/baz.
Последнее утверждение раскрывать требуется?
V>>В общем, когда речь идёт о реализации параметрического полиморфизма в C# vs C++ — то тут что-либо обсуждать сложно, т.к. у этих языков явно разные весовые категории в плане такого полиморфизма.
Q>Да, выражать констрейнты номинативно через типы — не лучший подход. Конечно, шаблоны в C++ мощнее (в этом же смысле генерация через T4 ещё «мощнее»). Но они непроверяемые. Вот код на C#, аналогичный приведённому выше плюсовому:
Q>
При наличии IBarable.Baz не ловится.
Ну и, в том же дотнете гораздо чаще случаются ошибки, когда вызывается не та сигнатура Bar, что ожидал разработчик. Тут только тесты помогут, повторюсь, которые должны проверить все ветки кода.
Q>Тут ошибка не только будет сразу подчёркнута в IDE, но ещё и по точке intellisense выдаст список допустимых ограничениями методов. Могут ли такое в C++ упомянутые «имеющиеся ср-ва языка в декларативном стиле, с полтыка найденные на этом сайте»?
В С++ intellisense уж точно не предложит никакого baz. ))
Ну и, опять повторюсь, что ограничения в стиле C# организовать можно:
Можно и помощнее ограничения задавать, ес-но, см. <type_traits>.
Q>Стадия компиляции не выявит ошибку даже в пользовательском коде, если у пользователя есть свой метод `baz()`, вызова которого из библиотечного кода он не ожидает. Ведь он ожидает, что согласно документации будет вызываться `bar()`.
Ошибки перегрузки ловятся тестами, а не компилятором, ваш КО.
Такая же ошибка могла быть и не в шаблонном коде, если у целевого Т есть некий baz, помимо bar. Без тестирования ф-ии foo эти рассуждения ни о чем.
V>>Более того, в С++ легко проверить наличие нужного метода/методов даже в декларативном стиле уже имеющимися ср-вами языка (т.е. ср-в языка достаточно для разработки библиотечных приблуд требуемой функциональности).
Q>Это ты не мне расскажи, а Страуструпу. А то он не в курсе, что концепты не нужны: http://www.stroustrup.com/good_concepts.pdf
1. Я не против любых будущих улучшений языка С++, которые не будут нарушать его строгость и последовательность.
2. Речь шла о том, что многое можно делать уже сейчас.
3. Концепт не спасёт от ошибки перегрузки в твоём примере насчет bar/baz.
Последнее утверждение раскрывать требуется?
V>>В общем, когда речь идёт о реализации параметрического полиморфизма в C# vs C++ — то тут что-либо обсуждать сложно, т.к. у этих языков явно разные весовые категории в плане такого полиморфизма.
Q>Да, выражать констрейнты номинативно через типы — не лучший подход. Конечно, шаблоны в C++ мощнее (в этом же смысле генерация через T4 ещё «мощнее»). Но они непроверяемые. Вот код на C#, аналогичный приведённому выше плюсовому:
Q>
interface IBarable
Q>{
Q> void Bar();
Q>}
Q>...
Q>static void Foo<T>(T t) where T: IBarable
Q>{
Q> t.Baz(); // Ошибка: Имелось в виду `t.Bar()`. Ловится компилятором автора библиотеки.
Q>}
Q>
При наличии IBarable.Baz не ловится.
Ну и, в том же дотнете гораздо чаще случаются ошибки, когда вызывается не та сигнатура Bar, что ожидал разработчик. Тут только тесты помогут, повторюсь, которые должны проверить все ветки кода.
Q>Тут ошибка не только будет сразу подчёркнута в IDE, но ещё и по точке intellisense выдаст список допустимых ограничениями методов. Могут ли такое в C++ упомянутые «имеющиеся ср-ва языка в декларативном стиле, с полтыка найденные на этом сайте»?
В С++ intellisense уж точно не предложит никакого baz. ))
Ну и, опять повторюсь, что ограничения в стиле C# организовать можно:
using namespace std;
#define where(A, Predicate, B) static_assert(Predicate<A, B>::value, "Predicate "#A" "#Predicate" "#B" is not satisfied")
template<typename T>
struct A {
void foo() {}
};
template<typename T>
struct B {
where(A<T>, is_base_of, T);
void bar(T * t) { t->foo(); } // ok
};
struct C : A<C> {};
struct D {};
B<C> bc; // ok
B<D> bd; // error C2338: Predicate A<T> is_base_of T is not satisfied
Можно и помощнее ограничения задавать, ес-но, см. <type_traits>.
Re[18]: Стадия компиляции
Здравствуйте, Qbit86, Вы писали:
Q>Стадия компиляции не выявит ошибку даже в пользовательском коде, если у пользователя есть свой метод `baz()`, вызова которого из библиотечного кода он не ожидает. Ведь он ожидает, что согласно документации будет вызываться `bar()`.
Ошибки перегрузки ловятся тестами, а не компилятором, ваш КО.
Такая же ошибка могла быть и не в шаблонном коде, если у целевого Т есть некий baz, помимо bar. Без тестирования ф-ии foo эти рассуждения ни о чем.
V>>Более того, в С++ легко проверить наличие нужного метода/методов даже в декларативном стиле уже имеющимися ср-вами языка (т.е. ср-в языка достаточно для разработки библиотечных приблуд требуемой функциональности).
Q>Это ты не мне расскажи, а Страуструпу. А то он не в курсе, что концепты не нужны: http://www.stroustrup.com/good_concepts.pdf
1. Я не против любых будущих улучшений языка С++, которые не будут нарушать его строгость и последовательность.
2. Речь шла о том, что многое можно делать уже сейчас.
3. Концепт не спасёт от ошибки перегрузки в твоём примере насчет bar/baz.
Последнее утверждение раскрывать требуется?
V>>В общем, когда речь идёт о реализации параметрического полиморфизма в C# vs C++ — то тут что-либо обсуждать сложно, т.к. у этих языков явно разные весовые категории в плане такого полиморфизма.
Q>Да, выражать констрейнты номинативно через типы — не лучший подход. Конечно, шаблоны в C++ мощнее (в этом же смысле генерация через T4 ещё «мощнее»). Но они непроверяемые. Вот код на C#, аналогичный приведённому выше плюсовому:
Q>
При наличии IBarable.Baz не ловится.
Ну и, в том же дотнете гораздо чаще случаются ошибки, когда вызывается не та сигнатура Bar, что ожидал разработчик. Тут только тесты помогут, повторюсь, которые должны проверить все ветки кода.
Q>Тут ошибка не только будет сразу подчёркнута в IDE, но ещё и по точке intellisense выдаст список допустимых ограничениями методов. Могут ли такое в C++ упомянутые «имеющиеся ср-ва языка в декларативном стиле, с полтыка найденные на этом сайте»?
В С++ intellisense уж точно не предложит никакого baz. ))
Ну и, опять повторюсь, что ограничения в стиле C# организовать можно:
Можно и помощнее ограничения задавать, ес-но, см. <type_traits>.
Или можно на основе is_base_of сделать предикат is_derived_from, поменяв аргументы-типы местами (для дотнетчиков так привычней).
Q>Стадия компиляции не выявит ошибку даже в пользовательском коде, если у пользователя есть свой метод `baz()`, вызова которого из библиотечного кода он не ожидает. Ведь он ожидает, что согласно документации будет вызываться `bar()`.
Ошибки перегрузки ловятся тестами, а не компилятором, ваш КО.
Такая же ошибка могла быть и не в шаблонном коде, если у целевого Т есть некий baz, помимо bar. Без тестирования ф-ии foo эти рассуждения ни о чем.
V>>Более того, в С++ легко проверить наличие нужного метода/методов даже в декларативном стиле уже имеющимися ср-вами языка (т.е. ср-в языка достаточно для разработки библиотечных приблуд требуемой функциональности).
Q>Это ты не мне расскажи, а Страуструпу. А то он не в курсе, что концепты не нужны: http://www.stroustrup.com/good_concepts.pdf
1. Я не против любых будущих улучшений языка С++, которые не будут нарушать его строгость и последовательность.
2. Речь шла о том, что многое можно делать уже сейчас.
3. Концепт не спасёт от ошибки перегрузки в твоём примере насчет bar/baz.
Последнее утверждение раскрывать требуется?
V>>В общем, когда речь идёт о реализации параметрического полиморфизма в C# vs C++ — то тут что-либо обсуждать сложно, т.к. у этих языков явно разные весовые категории в плане такого полиморфизма.
Q>Да, выражать констрейнты номинативно через типы — не лучший подход. Конечно, шаблоны в C++ мощнее (в этом же смысле генерация через T4 ещё «мощнее»). Но они непроверяемые. Вот код на C#, аналогичный приведённому выше плюсовому:
Q>
interface IBarable
Q>{
Q> void Bar();
Q>}
Q>...
Q>static void Foo<T>(T t) where T: IBarable
Q>{
Q> t.Baz(); // Ошибка: Имелось в виду `t.Bar()`. Ловится компилятором автора библиотеки.
Q>}
Q>
При наличии IBarable.Baz не ловится.
Ну и, в том же дотнете гораздо чаще случаются ошибки, когда вызывается не та сигнатура Bar, что ожидал разработчик. Тут только тесты помогут, повторюсь, которые должны проверить все ветки кода.
Q>Тут ошибка не только будет сразу подчёркнута в IDE, но ещё и по точке intellisense выдаст список допустимых ограничениями методов. Могут ли такое в C++ упомянутые «имеющиеся ср-ва языка в декларативном стиле, с полтыка найденные на этом сайте»?
В С++ intellisense уж точно не предложит никакого baz. ))
Ну и, опять повторюсь, что ограничения в стиле C# организовать можно:
using namespace std;
#define where(A, Predicate, B) \
static_assert(Predicate<A, B>::value, "Predicate "#A" "#Predicate" "#B" is not satisfied")
template<typename T>
struct A {
void foo() {}
};
template<typename T>
struct B {
where(A<T>, is_base_of, T);
void bar(T * t) { t->foo(); } // ok
};
struct C : A<C> {};
struct D {};
B<C> bc; // ok
B<D> bd; // error C2338: Predicate A<T> is_base_of T is not satisfied
Можно и помощнее ограничения задавать, ес-но, см. <type_traits>.
Или можно на основе is_base_of сделать предикат is_derived_from, поменяв аргументы-типы местами (для дотнетчиков так привычней).