定义一个函数签名,其中包含具有C++ 20个概念的参考

发布于 2025-01-22 23:26:51 字数 753 浏览 3 评论 0原文

我正在尝试使用C ++ 20概念来限制接口。在此界面中,我希望功能签名仅使用引用。由于某种原因,我不能这样做。有人会帮忙吗?

#include <concepts>

template <typename T>
concept MyInterface = requires(T t)
{
    // How do I specify a f(int&) instead of f(int) here?
    {t.f(int{})} -> std::integral;
};

struct X
{
    int f(int& i) { 
       return i; 
    }
};
static_assert(MyInterface<X>);


/*
** While tempting, this is _NOT_ a solution. **
template <typename T>
concept MyInterface = requires(T t, int& i) // Add a requirement here.
{
    {t.f(i)} -> std::integral;
};

// This will compile, despite allowing `i` to be an int. 
// When really, it should be a int&.
X::f(int i) { return i };
*/

I am trying to use C++20 Concepts to constrain an interface. In this interface, I want a function signature to only use references. For some reason, I can't do this. Would someone help?

#include <concepts>

template <typename T>
concept MyInterface = requires(T t)
{
    // How do I specify a f(int&) instead of f(int) here?
    {t.f(int{})} -> std::integral;
};

struct X
{
    int f(int& i) { 
       return i; 
    }
};
static_assert(MyInterface<X>);


/*
** While tempting, this is _NOT_ a solution. **
template <typename T>
concept MyInterface = requires(T t, int& i) // Add a requirement here.
{
    {t.f(i)} -> std::integral;
};

// This will compile, despite allowing `i` to be an int. 
// When really, it should be a int&.
X::f(int i) { return i };
*/

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

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

发布评论

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

评论(2

凉墨 2025-01-29 23:26:51

我不同意此评论,这绝对是一个解决方案(除非您不必使i int&amp;int足够):

template <typename T>
concept MyInterface = requires(T t, int i)
{
    {t.f(i)} -> std::integral;
};

也就是说,实际上是您的界面:您正在将lvalue int传递到成员函数f中,并且您希望它返回某种满足Integral的类型代码>。


为了拒绝服用int的卡利斯,您必须通过一些不同的类型 - 例如可转换为int&amp;的东西,而不是直接:

template <typename T>
concept MyInterface = requires(T t, std::reference_wrapper<int> i)
{
    {t.f(i)} -> std::integral;
};

或者另外拒绝其他情况:

template <typename T>
concept MyInterface =
    requires(T t, int i) { {t.f(i)} -> std::integral; }
    && !requires(T t){ t.f(42); };

传递Reference_wrapper&lt; int&gt;是...确定。明确拒绝服用int rvalues似乎充其量似乎值得怀疑。

I disagree with this comment, this is absolutely a solution (except you don't have to make i an int&, int suffices):

template <typename T>
concept MyInterface = requires(T t, int i)
{
    {t.f(i)} -> std::integral;
};

That is, indeed, your interface: you're passing an lvalue int into the member function f and you expect it to return some type which satisfies integral.


In order to reject callees taking int, you have to either pass some different type - like something convertible to int& instead of directly that:

template <typename T>
concept MyInterface = requires(T t, std::reference_wrapper<int> i)
{
    {t.f(i)} -> std::integral;
};

or then additionally reject the other case:

template <typename T>
concept MyInterface =
    requires(T t, int i) { {t.f(i)} -> std::integral; }
    && !requires(T t){ t.f(42); };

Passing reference_wrapper<int> is... ok. Explicitly rejecting taking int rvalues seems questionable at best.

情深如许 2025-01-29 23:26:51

您可以利用std :: dectval为约束创建参考类型:

template <typename T>
concept MyInterface = requires(T t)
{
    {t.f(std::declval<int&>())} -> std::integral;
};

请注意,这仍然允许t :: f(int)工作。要禁止它,您可以对此添加另一个约束:

template <typename T>
concept MyInterface = requires(T t)
{
    {t.f(std::declval<int&>())} -> std::integral;
}
&& !requires(T t)
{
    {t.f(std::declval<int>())} -> std::integral;
};

You can utilize std::declval to create a reference type for the constraint:

template <typename T>
concept MyInterface = requires(T t)
{
    {t.f(std::declval<int&>())} -> std::integral;
};

Note that this would still allow T::f(int) to work. To disallow it, you can add another constraint to it:

template <typename T>
concept MyInterface = requires(T t)
{
    {t.f(std::declval<int&>())} -> std::integral;
}
&& !requires(T t)
{
    {t.f(std::declval<int>())} -> std::integral;
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文