C++ has some sort of duck typing for types given by template parameters. We have no idea what type DUCK1 and DUCK2 will be, but as long as they can
DUCK1
DUCK2
We only need to write one version of the function:
#include template void let_them_quack(Quackers&& ...quackers) { using expand = int[]; void(expand { 0, (std::forward(quackers).quack(), 0)... }); } struct Duck { void quack() {} }; int main() { Duck a, b, c; let_them_quack(a, b, c, Duck()); }