【发布时间】:2021-04-23 14:55:00
【问题描述】:
我目前正试图让我的脚湿透概念。让我们假设我有一个概念:
template <class T> concept Initable = requires (T&t) { { init(t) }; };
// just for demonstration purposes, real concept makes more sense ...
我想为像std::optional 这样的第三方类提供一个采用层来实现这个概念,对我来说最简单的方法是什么?
很明显,下面这段代码失败了:
template <std::semiregular T>
T& init(std::optional<T> &v) { /* contents not that important */ v = T{}; return *v; }
static_assert(Initable<std::optional<int>>, "Oh no!"); // Fails!
原因是两阶段查找。
当尝试在第 1 阶段解决 Initable 概念中的 init 时,我对 init 的定义不可用,因为它在Initable 概念下方提供。 p>
在第 2 阶段尝试解决它时,我的定义无法通过依赖于参数的查找找到,因为它未在 std 命名空间中提供。
因此,两个明显的解决方案是在定义 Initable 概念之前提供 init 的定义,或者将 init 移动到 std 命名空间。
但我想在没有的情况下为std::optional 实现这个概念
- 依赖于特定的定义/包含顺序,
- 填充
std命名空间和 - 在调用方站点使用过多样板代码。
最好的方法是什么?在定义 Initable 概念时,是否可以更轻松地实现这一点?
基本上我在问,this 可能吗?
#include <concepts>
#include <optional>
template <class T>
concept Initable =
requires (T& t) { init(t); } // May be changed to make the task easier.
;
// Insert code *here* that magically makes std::optional implement Initable.
static_assert(Initable<std::optional<int>>, "std::optional is not initable!");
如果不是,那么下一个最好的事情是什么?
【问题讨论】:
-
我不明白你在做什么。您的架构中似乎有太多您不清楚的组件:您实现了什么(可能是一个库?)、用户(您的代码的消费者)和第 3 方库。你定义了一个概念,但这个概念“可以由用户实现”是什么意思?要么你实现这个概念,要么你的用户实现这些概念。对我个人来说没有意义。 “将它们与我假设的图书馆一起使用。”除非您拥有并重写该库,否则您无法将概念添加到现有库中。
-
@bolov:我的库:定义概念,第三方库:提供未实现该概念的类,用户代码:在第三方类之上实现概念,然后想将该类用作如果它实现了这个概念。当这样说时,它归结为扩展第三方类的公共接口。现在我意识到我可能要求的太多了。
-
要么我误解了你,要么你误解了概念。一个类不会“声明”实现一个概念。一个类要么满足一个概念,要么不满足。如果你定义一个概念(例如默认可初始化),一个类将满足这个概念,如果它是默认可初始化的。
-
你的sn-ps代码不足以理解你的问题。你能创建一个小的minimal reproducible example吗?
-
@bolov:我试图重新表述这个问题,希望现在更清楚?
标签: c++ argument-dependent-lookup