【问题标题】:Is there a way to use a using-declaration inside a requires-expression有没有办法在 requires-expression 中使用 using-declaration
【发布时间】:2022-12-03 01:27:44
【问题描述】:

我想测试一个类型是否可以传递给某个函数,但我想在函数查找中使用 ADL 并包含来自某个命名空间的函数。

考虑这段代码:

#include <utility>
#include <vector>

template<class T>
concept Swappable = requires(T& a, T&b)
{
    swap(a,b);
};

static_assert(Swappable<std::vector<int>>); // #1
static_assert(Swappable<int>); // #2

#1 成功,它找到了 std::swap,因为 stdstd::vector&lt;int&gt; 的关联命名空间。但是 #2 失败了,内置类型没有关联的命名空间。

我怎么会写这样的东西:

template<class T>
concept Swappable = requires(T& a, T&b)
{
    using std::swap; // illegal
    swap(a,b);
};

AFAIK,您不能在必需的表达式中使用 using 声明。

编辑作为一种解决方法,我可以在一个单独的命名空间中实现这个概念,在这个命名空间中引入了名称。对此不太满意,但它确实有效。

namespace detail
{
    using std::swap;

    template<class T>
    concept Swappable = requires(T& a, T&b)
    {
        swap(a,b);
    };
}

// and then either uses it
using detail::Swappable;

// or redefine it
template<class T>
concept Swappable = detail::Swappable<T>;

【问题讨论】:

  • 这实际上是一个有用的概念吗?如果你在Swappable上约束一个模板参数,你仍然必须using std::swap是安全的
  • 但在我的特殊情况下,如果为它定义了一组特定的函数,我希望代码以某种方式运行,如果没有,则以另一种方式运行。所以我想有一个概念来测试它。
  • @oisyn:“如果为它定义了一组特定的函数,我希望代码以某种方式运行,如果没有,则以另一种方式运行。" 然后你将不得不解释这种行为是什么,以及为什么你需要它来拥有这种行为。如果你给出的例子过于简单化,那么我们将给你过于简单化的答案。
  • 我的问题很简单。如何在 requires 表达式中使用 using 声明。我从语言的角度问,我不关心潜在的 xy 问题。

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


【解决方案1】:

避免使用旧的 using-based 习语。相反,使用自定义点等价物,如 ranges::swap

也就是说,您不应该要求用户在他们的代码中使用基于using 的习语。提供一个定制点对象来完成它所需要的。 operator() 重载/模板可以被约束以创建 using 习语的效果,而不需要用户实际调用 using

ranges::swap is a good example of how this gets done.

【讨论】:

    猜你喜欢
    • 2019-06-12
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    • 2012-05-17
    • 2015-10-16
    • 2023-04-08
    • 1970-01-01
    • 2014-06-13
    相关资源
    最近更新 更多