如果指定两个要求,为什么我的概念不起作用

发布于 2025-02-08 16:24:31 字数 2254 浏览 0 评论 0原文

我有以下代码:

#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;
};

如果删除行t.get_int(s)} - &gt; std :: Same_as&lt; int&gt ;;从概念operatorlike中似乎一切正常。我不确定为什么添加此附加要求会给我一个编译错误。编译错误还仅指以下事实:运行方法没有匹配函数,这是因为不满足可获取的概念。但是根本原因看起来像是操作员概念的

另一个观察结果是,如果我从操作员概念中删除所有const,这一切似乎都起作用,包括其他要求

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

美人骨 2025-02-15 16:24:31

复合需求

{ t.get_int(s) } -> std::same_as<const int>;

测试是否decltype(((t.get_int(s)))const int相同。但是,这是一个毫无意义的测试,因为没有const非类型类型的prvalues,这将是exlytype可以导致const的唯一表达式。 int

非类型类型的prvalue始终将其const剥离。因此,即使get_int声明返回const int,呼叫表达式的类型t.get_int(s)将始终为> int,而不是const int

通常,在返回类型上具有顶级const几乎总是没有用的。我唯一能想到的用例是您要禁止调用non- const成员函数的类型返回值,而不必先存储在变量中,但是有更好的方法可以实现这一目标(例如&amp; qualified成员功能)。

The compound requirement

{ t.get_int(s) } -> std::same_as<const int>;

tests whether decltype((t.get_int(s))) is the same as const int. However, that is a pointless test, because there are no const prvalues of non-class type and these would be the only expressions for which decltype could result in const int.

A prvalue of non-class type will always have its const stripped. So even if get_int is declared to return const int, the type of the call expression t.get_int(s) will always be int, not const int.

In general having top-level const on a return type is almost always useless. The only use case I can think of is a class type return value for which you want to disallow calling non-const member functions without storing in a variable first, but there are better ways of achieving that (e.g. &-qualified member functions).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文