Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

In C++, the signature of a function template doesn't necessarily tell you what types you can successfully call it with, nor what the return type is.

Much analysis is delayed until all templates are instantiated, with famously terrible consequences for error messages, compile times, and tools like IDEs and linters.

By contrast, rust's monomorphization achieves many of the same goals, but is less of a headache to use because once the signature is satisfied, codegen isn't allowed to fail.



> In C++, the signature of a function template doesn't necessarily tell you what types you can successfully call it with, nor what the return type is.

That's the whole point of Concepts, though.


Concepts are basically a half solution - they check that a type has some set of properties, but they don't check that the implementation only uses those properties. As a result, even with concepts you can't know what types will work in a template without looking at the implementation as well.

Example [0]:

    #include <concepts>

    template<typename T>
    concept fooable = requires(T t) {
        { t.foo() } -> std::same_as<int>;
    };

    struct only_foo {
        int foo();
    };

    struct foo_and_bar {
        int foo();
        int bar();
    };

    template<fooable T>
    int do_foo_bar(T t) {
        t.bar(); // Compiles despite fooable not specifying the presence of bar()
        return t.foo();
    }

    // Succeeds despite fooable only requiring foo()
    template int do_foo_bar<foo_and_bar>(foo_and_bar t);

    // Fails even though only_foo satisfies fooable
    template int do_foo_bar<only_foo>(only_foo t);
[0]: https://cpp.godbolt.org/z/jh6vMnajj


> they check that a type has some set of properties, but they don't check that the implementation only uses those properties.

I'd say that's a mistake of the person who wrote the template then.

Also, there are Concepts where you absolutely know which types are allowed, e.g. std::same_as, std::integral, std::floating_point, etc.


> I'd say that's a mistake of the person who wrote the template then.

The fact that it's possible to make that mistake is basically the point! If "the whole point of concepts" were to "tell you what types you can successfully call it with" then that kind of mistake should not be possible.

It's true that there are certain cases where you know the full set of types you can use, but I'd argue that those are the less interesting/useful cases, anyways.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: