【问题标题】:How to require the existence of a function in a constraint?如何要求约束中存在函数?
【发布时间】:2020-11-07 14:57:29
【问题描述】:

我有一个带有自定义Vector 类的文件vector.h,其中向量条目的数据类型应限制为实现函数f 的类型:

template <typename T>
concept Vector_Type = requires (T a) {
    f(a);
};

template <Vector_Type T>
class Vector {};

此外,我有多个文件,其中为不同的数据类型定义了函数 f,例如以下datatype_int.h 头文件:

int f(int a) { return 2*a; }

如果我在vector.h 之后包含datatype_int.h,编译器会抱怨不满足约束:

#include "vector.h"
#include "datatype_int.h"

int main() {
    Vector<int> v;  // Error: constraints not satisfied

    return 0;
}

这不是一个很有帮助的错误消息,我想避免依赖于包含的顺序。但是,无法在vector.h 中为所有可能的数据类型T 声明函数f,因为我不知道将使用哪些数据类型。

我该如何解决这个问题?

【问题讨论】:

  • 我认为没有办法解决这个问题。对于具有类类型的Vector 的实例化,该概念应该通过ADL 找到合适的f,但要使用内置类型,我认为您别无选择,只能在概念定义之前声明f。跨度>
  • 听到我打算做的事情实际上适用于类类型,我很惊讶。我刚刚测试了它,它工作得非常好。类类型和内置类型之间存在这种差异的原因是什么?这已经在很大程度上解决了我的问题。
  • 这与ADL有关。对于采用类类型的fs,ADL 将在关联的命名空间中查找所有fs,因此它可以工作。 ADL 不适用于内置类型,因此您要查找的声明需要在您需要查找发生的点之前按词法声明。
  • 现在我再想一想,这可能可以通过模块而不是文本包含来解决,但我对模块或 ADL 如何与之交互的了解还不够。

标签: c++ c++20 c++-concepts


【解决方案1】:

我不确定这种设计是否可行,但问题的症结在于int 是一个内置类型。如果您有用于调用f 的特殊类型,您将能够延迟f 的查找直到实例化。

例如:

struct enabler{};

template <typename T>
concept Vector_Type = requires (T a) {
    f(a, enabler{});
};

template <Vector_Type T>
class Vector {};

int f(int a, enabler = {}) { return 2*a; }

int main() {
    Vector<int> v; 
    return 0;
}

【讨论】:

  • 这看起来很合理,尽管您应该默认f 的第二个参数,即int f(int a, enabler = {}),因此f 的调用者不必担心该实现细节。
猜你喜欢
  • 1970-01-01
  • 2019-04-22
  • 2023-02-20
  • 1970-01-01
  • 2020-02-12
  • 2016-04-19
  • 2019-04-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多