Has anyone proposed something like this?

---
interface sizeable {
    size_t size() cost;
}

bool too_big(sizeable thing) {
      return thing.size() > 100;
}

void main() {
    std::cout << too_big(string("sdfkjhsdfjh")) << std::endl;
    std::cout << too_big(vector<int>(1000,0)) << std::endl;
}
---

the precompiler can then generate specializations as needed, in the same way that templates generate specializations, so the resulting code can be as efficient as templates

the advantage is that

 - it's just as efficient as templates
 - it's easier to teach/understand
 - avoids virtual stuff
 - avoids complex inheritance
 - works with existing libs
 - should result in much better error messages than templates