我们如何测试是否可以使用prvalue调用某种类型的表达式? [英] How do we test if an expression of a certain type can be invoked with a prvalue?

查看:115
本文介绍了我们如何测试是否可以使用prvalue调用某种类型的表达式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

带有我们有精美的新 is_invocable 和精美的新prvalue真的不值钱.

With c++17 we have fancy new is_invocable and fancy new prvalues that aren't really values.

这使您可以创建对象,而不必先进行逻辑构造,然后再取消构造.

This permits you to create an object without having to first logically construct it, then elide the construction.

我遇到了一个问题,其中使用std::is_invocable来测试您是否可以调用某些内容,并且prvalue规则似乎冲突:

I have run into a problem where using std::is_invocable to test if you can call something, and prvalue rules, seem to collide:

struct no_move {
  no_move(no_move&&)=delete;
  explicit no_move(int) {}
};
void f( no_move ) {}

现在我们可以问一下是否可以使用类型为no_move的prvalue调用f吗?

now can we ask if f can be invoked using a prvalue of type no_move?

f( no_move(1) )

std::is_invocable< decltype(&f), no_move >不起作用,因为它使用了std::declval<no_move>(),它是类似于no_move&&的x值,而不是类型为no_move的prvalue.

std::is_invocable< decltype(&f), no_move > doesn't work because it uses std::declval<no_move>() which is an xvalue like no_move&& not a prvalue of type no_move.

c ++ 14 相同,但是保证省略可以使某些函数可以使用xvalue调用(即"T&&"),而其他函数可以使用类型为T的prvalue.

In c++14 this was the same, but guaranteed elision makes some functions callable with an xvalue (i.e., "T&&") and others with prvalues of type T.

是否有其他选择,还是我们必须发明自己的特征来处理这种情况?

Is there an alternative, or do we have to invent our own trait to handle this case?

(在理论上,std::declval<T>返回T而不是T&&,我相信is_invocable将做正确的事情.)

(In a theoretical world where std::declval<T> returned T instead of T&&, is_invocable would, I believe, do the right thing).

推荐答案

是否有其他选择,还是我们必须发明自己的特征来处理这种情况?

Is there an alternative, or do we have to invent our own trait to handle this case?

是的,您只需要编写自己的不使用declval的特征即可.假设您周围有 std::is_detected (我知道您当然可以这么做) :

Yeah, you'd just have to write your own trait that doesn't use declval. Assuming you have std::is_detected lying around (which I know you certainly do):

template <typename T> T make();

template <typename F, typename... Args>
using invoke_result_t = decltype(std::declval<F>()(make<Args>()...));
//                               ^^^^^^^^^^^^^     ^^^^^

template <typename F, typename... Args>
using is_invocable = std::is_detected<invoke_result_t, F, Args...>;

这样,std::is_invocable<decltype(f), no_move>false_type,而is_invocable<decltype(f), no_move)>true_type.

我故意将declval<F>()用作函数,而不是make,以便允许在此处使用decltype(f).的确,invoke_result_t应该更复杂,并且对成员的指针等执行正确的操作".但这至少是一个简单的近似值,表明了这种方法的可行性.

I intentionally use declval<F>() for the function instead of make so as to allow using decltype(f) here. Really, invoke_result_t should be more complicated, and "do the right thing" for pointers to members, etc. But this is at least a simple approximation that indicates the viability of this approach.

这篇关于我们如何测试是否可以使用prvalue调用某种类型的表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆