Search code examples
c++templatesconstraintsc++20

Abbreviated function template. "Constraint auto const&" type works, but "Constaint const auto&" fails


For boost container hash, I needed to provide an ADL-reachable hash_value. I wanted to disable implicit conversions, so I wrote it as a template that forced the parameter to be the class type.

inline auto hash_value(std::same_as<ClassType> const auto& key) -> std::size_t;

To my surprise, it failed, but worked if I swapped the order of const and auto.

In order to build up a deeper understanding: How can I conceptually interpret this situation? The parameter has a placeholder type const auto& and is given a specifier that denotes a constraint, I thought until now. But this rather appears to be a case where the sequence constraint auto is a grammar that's specially detected and the mechanism fails if I reorder the type specifiers.


Solution

  • mechanism fails if I reorder the type specifiers

    Correct. Because the constraint is not a type specifier on its own. Grammatically, it's part of the placeholder type itself

    placeholder-type-specifier:
        type-constraintopt auto
        type-constraintopt decltype ( auto )
    

    There is no room there for other specifiers. Conversely, this does work:

    inline auto hash_value(const std::same_as<ClassType> auto& key) -> std::size_t;
    

    If you are in the wrong left const camp, and not the right camp.