【问题标题】:How to write a c++ concept for Heuristic function如何为启发式函数编写 C++ 概念
【发布时间】:2020-04-18 07:59:26
【问题描述】:

我正在 c++ 20 中实现一个带有启发式函数的搜索算法。 我试图用这样的概念来限制我的算法可以使用的函数:

template<typename SelfType, unsigned from, unsigned to>
concept Heuristic = requires(SelfType h, unsigned current)
{
    { h(current) } -> unsigned;

    assert(h(to) == 0);
};

然后我可以写这样的东西:

template<unsigned from, unsigned to>
struct H
{
    unsigned operator()(unsigned current)
    {
        return to - current + 100;
    }
};

当然断言不起作用,这不是一个有效的启发式,因为这里 h(to) 是 100。我想让编译器在编译时检查 h(to) 等于 0。

【问题讨论】:

  • 需求中不能有断言。抛开概念不谈,如果无法在编译时评估 h(to),您希望编译器如何验证 h(to) == 100? (在您的示例中它不是一个常量表达式,因为operator() 不是constexpr。)
  • 您使用的是哪个编译器?即使您删除了 assert,这个 (-&gt; unsigned;) 也是无效的。正确的写法是使用-&gt; std::same_as&lt;unsigned&gt;;-&gt; std::convertible_to&lt;unsigned&gt;;

标签: c++ c++20 heuristics concept


【解决方案1】:

我想让编译器检查 h(to) 等于 0 的编译时间。

这只有在编译器能够在编译时调用h(to) 时才有可能。它不能,因为不能保证调用的任何函数都是constexprSelfType 可以是函数指针类型,函数指针不携带 constexpr。而概念甚至无法检查某事物是否为常量表达式。

当您开始考虑值是否映射到正确的域或函数是否将值映射到域的问题时,这不再是一个真正的“概念”。或者至少,它不是语言特征意义上的概念。

也就是说,当我们认为某些东西是语言无法验证的概念的特定用户的需求时。 C++20 概念库中充满了这些公理化的概念要求。

这也是您应该使用命名成员函数进行启发式的一个很好的理由,而不是假设任何具有operator() 重载的东西恰好从无符号整数映射到无符号整数是“启发式” .

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-02
    • 2015-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多