Здравствуйте, vdimas, Вы писали:
V>Похоже, что ты забываешь, что речь всё еще о стадии компиляции и такое несоответствие "констрейнам" (возникни оно в коде) в С++ в любом случае именно на этой стадии обнаруживается.
Стадии компиляции
у пользователя, а не у автора библиотечного кода — огромная разница. Более того, даже там ошибка может не обнаружиться. Например:
// template <typename T>
// concept bool Barable = requires(T t)
// {
// { t.bar() } -> void;
// };
template <typename T>
// requires Barable<T>
void foo(T t)
{
t.baz(); // Ошибка: имелось ввиду `t.bar()`. Не ловится компилятором автора библиотеки.
}
Стадия компиляции не выявит ошибку даже в пользовательском коде, если у пользователя есть свой метод `baz()`, вызова которого из библиотечного кода он не ожидает. Ведь он ожидает, что согласно документации будет вызываться `bar()`.
V>Более того, в С++ легко проверить наличие нужного метода/методов даже в декларативном стиле уже имеющимися ср-вами языка (т.е. ср-в языка достаточно для разработки библиотечных приблуд требуемой функциональности).
Это ты не мне расскажи, а Страуструпу. А то он не в курсе, что концепты не нужны:
http://www.stroustrup.com/good_concepts.pdf
V>В общем, когда речь идёт о реализации параметрического полиморфизма в C# vs C++ — то тут что-либо обсуждать сложно, т.к. у этих языков явно разные весовые категории в плане такого полиморфизма.
Да, выражать констрейнты номинативно через типы — не лучший подход. Конечно, шаблоны в C++ мощнее (в этом же смысле генерация через T4 ещё «мощнее»). Но они непроверяемые. Вот код на C#, аналогичный приведённому выше плюсовому:
interface IBarable
{
void Bar();
}
...
static void Foo<T>(T t) where T: IBarable
{
t.Baz(); // Ошибка: Имелось в виду `t.Bar()`. Ловится компилятором автора библиотеки.
}
Тут ошибка не только будет сразу подчёркнута в IDE, но ещё и по точке intellisense выдаст список допустимых ограничениями методов. Могут ли такое в C++ упомянутые «имеющиеся ср-ва языка в декларативном стиле, с полтыка найденные на этом сайте»?