Search code examples
c++c++20c++-concepts

concepts template argument deduction


The concept below has two template parameters but only one is specified during usage. Is T always deduced and InnerType always the parameter that needs explicit specification?

#include <iostream>
#include <string>
#include <span>

template < class T, class InnerType >
concept RangeOf = requires(T&& t) 
{
    requires std::same_as<std::remove_cvref_t<decltype(*std::ranges::begin(t))>, InnerType >;
    std::ranges::end(t);
};

void print(const RangeOf<char> auto& seq) {
    std::cout << "char seq: " << std::string_view(seq.data(), seq.size()) << std::endl;
}

int main() {    
    auto a_view = std::string_view("hello");
    print(a_view);
}

Solution

  • When you use concepts with templates as you did there, the type you are trying to constraint matches the very first type-argument. Everything else you specify comes after that in the order you specified. Here's a simplified example:

    #include <concepts>
    
    template <class T1, class T2, class T3>
    concept ThreeTypes = std::same_as<T1, int> &&
                         std::same_as<T2, short> && 
                         std::same_as<T3, long>;
    
    
    template <ThreeTypes<short, long> T>
    void foo(T t) {
    
    }
    
    int main() {
        foo(14); // OK
        // foo(14.1); // Won't compile
    }
    

    See online.