I have the following code:
#include <concepts>
#include <functional>
#include <iostream>
template<typename T>
concept OperatorLike = requires(T t, const std::string s) {
{ t.get_string(s) } -> std::same_as<const std::string>;
{ t.get_int(s) } -> std::same_as<const int>;
};
template<typename T, typename O>
concept Gettable = requires(T t, O op) {
t.apply_get(0, op);
t.apply_post(0, op); };
template<std::semiregular F>
class RestApiImpl {
F m_get_method;
public:
RestApiImpl(F get = F{}) : m_get_method{std::move(get)} {}
void register_get(F functor) {
m_get_method = std::move(functor);
}
template<OperatorLike IF>
requires std::invocable<F, const int, IF>
void apply_get(const int req, IF interface){
m_get_method(req, std::move(interface));
}
template<OperatorLike IF>
requires std::invocable<F, const int, IF>
void apply_post(const int req, IF interface){
m_get_method(req, std::move(interface));
}
};
class ASpecificJSONLibrary{
public:
std::string operator[](std::string key){
return key + "_withLambda";
}
};
class Server{
public:
ASpecificJSONLibrary libObj; // this is a
struct impl;
void run(Gettable<impl> auto& api){
api.apply_get(0, impl(*this));
}
struct impl {
public:
Server& m_server;
impl(Server& server ) : m_server(server){}
const std::string get_string(const std::string key) {
return (m_server.libObj)[key];
};
const int get_int(std::string const key) {
return 1;
}
};
};
int main(){
auto get = [](int, OperatorLike auto intf){
std::string dummy = "dummy";
std::cout << intf.get_string(dummy);
};
RestApiImpl api(get);
Server server;
server.run(api);
return 0;
};
If remove the line t.get_int(s) } -> std::same_as<int>; from the concept OperatorLike everything seems to work as it should. I am not sure why adding this additional requirement gives me a compile error. The compile error also refers only to the fact that the there is no matching function to the run method, which is because the Gettable concept is not satisfied. But the root cause looks like it is the OperatorLike concept
Another observation just made is that if I remove all the consts from the operatorLike concept it all just seem to work including the additional requirements