这个不完整的类型可以改进以与这个 C++ 一起使用吗?概念?

发布于 2025-01-14 18:02:47 字数 1594 浏览 3 评论 0原文

以下代码工作按照 g++ 9.3.1 和旧概念 TS 设计。但我还没有让它与 g++ 10.3.1 和概念的 C++ 核心语言版本一起使用:

#if __cpp_concepts < 201707
#  define CONCEPT concept bool
#else
#  define CONCEPT concept
#endif

template<class T>
CONCEPT AcceptsEvents = requires (T t) {
  t.OnEvent();
};

template <AcceptsEvents T>
struct Inner { };

struct Outer {
  void OnEvent();
  Inner<Outer> inner;
};

int main() {
  Outer out;
}

这是我使用概念 TS 进行的 g++ 9.3.1 编译:

$ g++ -std=c++2a -fconcepts concepts.cpp

它构建时没有错误。

这是我使用 C++ 概念核心语言功能进行的 g++ 10.3.1 编译:

$ g++ -std=c++2a -fconcepts-diagnostics-depth=2 concepts.cpp

这无法编译,并显示以下解释的错误消息:

note: constraints not satisfied
required for the satisfaction of 'AcceptsEvents<T>' [with T = Outer]
 in requirements with 'T t' [with T = Outer]
note: the required expression 't.OnEvent()' is invalid, because
error: 't' has incomplete type

我已阅读 概念 TS核心语言概念 页面详细位于 cppreference.com,并且我已阅读这个SO答案试图将class Outer变成一个完整的类型。对于设计改进以使 10.3.1 版本像旧的 9.3.1 版本一样工作有什么建议吗?

The following code works as designed with g++ 9.3.1 and the old concepts TS. But I haven't gotten it to work with g++ 10.3.1 and the C++ core language version of concepts:

#if __cpp_concepts < 201707
#  define CONCEPT concept bool
#else
#  define CONCEPT concept
#endif

template<class T>
CONCEPT AcceptsEvents = requires (T t) {
  t.OnEvent();
};

template <AcceptsEvents T>
struct Inner { };

struct Outer {
  void OnEvent();
  Inner<Outer> inner;
};

int main() {
  Outer out;
}

Here's my g++ 9.3.1 compilation with concepts TS:

$ g++ -std=c++2a -fconcepts concepts.cpp

It builds with no errors.

Here's my g++ 10.3.1 compilation with the C++ concepts core language feature:

$ g++ -std=c++2a -fconcepts-diagnostics-depth=2 concepts.cpp

This fails to compile with the following paraphrased error message:

note: constraints not satisfied
required for the satisfaction of 'AcceptsEvents<T>' [with T = Outer]
 in requirements with 'T t' [with T = Outer]
note: the required expression 't.OnEvent()' is invalid, because
error: 't' has incomplete type

I've read both the concepts TS and core language concepts pages at cppreference.com in detail, and I've read this SO answer in an effort to coax class Outer into a complete type. Any suggestions for design improvements to get the 10.3.1 version working like the old 9.3.1 version was?

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

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

发布评论

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

评论(2

旧城烟雨 2025-01-21 18:02:47

您可以分离事件逻辑。根据您的数据结构,这可能有意义,也可能没有意义。

继承

struct Event
{
    void OnEvent();
};

struct Outer : Event {
  Inner<Event> inner;
};

构成

struct Event
{
    void OnEvent();
};

struct Outer {
  Event evt;
  Inner<Event> inner;
};

You can separate the event logic. Depending on your data structures this could make sense or not.

Inheritance

struct Event
{
    void OnEvent();
};

struct Outer : Event {
  Inner<Event> inner;
};

Composition

struct Event
{
    void OnEvent();
};

struct Outer {
  Event evt;
  Inner<Event> inner;
};
原野 2025-01-21 18:02:47
auto OnEvent(auto& t)->decltype(t.OnEvent()){
  return t.OnEvent();
}

template<class T>
concept AcceptsEvents = requires (T t) {
  OnEvent(t);
};

template <AcceptsEvents T>
struct Inner { };

struct Outer;
void OnEvent(Outer&);

struct Outer {
  void OnEvent();
  Inner<Outer> inner;
};

void OnEvent(Outer&o){o.OnEvent();}

那应该有效。未经测试,对概念的实践经验很少,因此可能是错误的;但对我的头编译器来说似乎是正确的。

我将概念从需要方法更改为函数调用。然后添加一个调用该方法的蹦床模板。所以它会检查两者;现有类型(完成后)应该可以工作。

这让我们可以在不完整的 Outer 对象上定义一个自由函数,因此 Outer 通过测试。

添加一些名称空间,我们甚至可以调用蹦床。

auto OnEvent(auto& t)->decltype(t.OnEvent()){
  return t.OnEvent();
}

template<class T>
concept AcceptsEvents = requires (T t) {
  OnEvent(t);
};

template <AcceptsEvents T>
struct Inner { };

struct Outer;
void OnEvent(Outer&);

struct Outer {
  void OnEvent();
  Inner<Outer> inner;
};

void OnEvent(Outer&o){o.OnEvent();}

that should work. Not tested, little practical experience with concepts, so it could be wrong; but seems right to my head-compiler.

I changed the concept from requireing a method to a function call. Then added a trampoline template that calls the method. So it checks both; and existing types (when complete) should work.

This lets us define a free function on an incomplete Outer object, so Outer passes the test.

Throw in some namespaces and we can even call the trampoline.

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