Много лет назад (по крайней мере для меня) статический полиморфизм С ++ казался последовательным. Такие языки, как Python, полагались на утка печатать, где у вас есть:
def fn(foo, bar):
foo.baz(bar.bo())
и идея состояла в том, что, если это «крякало» должным образом, это было хорошо языком.
В C ++, наоборот, вам придется объяснить, что это за «животное»:
void fn(foo_type foo, bar_type bar);
и для «королевств семей» вам явно нужно использовать template
ключевое слово:
template<class Foo, class Bar>
void fn(Foo foo, Bar bar);
С новыми функциями, такими как auto ...() -> decltype
типы возврата, но особенно общие лямбды, кажется, что-то гораздо более похожее на не-шаблонную Python-подобную утку:
[] (auto container) { return container.size(); };
Мой вопрос, поэтому, почему template
ключевое слово еще нужно? Почему бы просто не охватить (необязательно) печатание на утке:
// Takes a foo_type and a bar_type
void fn(foo_type foo, bar_type bar);
// Takes some "foo-quacking" type, and a bar_type
void fn(auto foo, bar_type bar);
// Etc.
Это на самом деле почти у двери, как часть Концепции функция, и некоторые компиляторы уже реализуют ее! Например, с GCC 4.9, если вы укажете -std=c++1y
вы можете скомпилировать и запустить следующее:
auto print_arg(auto arg) {
std::cout << arg;
}
Других решений пока нет …