如果指定两个要求,为什么我的概念不起作用
我有以下代码:
#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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
复合需求
测试是否
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
tests whether
decltype((t.get_int(s)))
is the same asconst int
. However, that is a pointless test, because there are noconst
prvalues of non-class type and these would be the only expressions for whichdecltype
could result inconst int
.A prvalue of non-class type will always have its
const
stripped. So even ifget_int
is declared to returnconst int
, the type of the call expressiont.get_int(s)
will always beint
, notconst 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).