接合模板不会短路 [英] Conjuction template doesn't short circuit

查看:74
本文介绍了接合模板不会短路的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够评估一个函数是否接受一个int类型的参数,以及它是否返回void。为此,我使用了 std :: conjunction ,因为我认为它应该短路并且不评估第二个格式错误的表达式,以防该函数不能被一个调用。类型为int的参数,但由于某种原因,我收到了编译器错误:

I want to be able to evaluate whether a function accepts one argument of type int, and whether it returns void. To that end I used std::conjunction since I believed it was supposed to short-circuit and not evaluate the second ill-formed expression in case the function is not callable with one argument of type int, but for some reason I get a compiler error:

#include <iostream>
#include <type_traits>
template<typename Function>
struct oneArgVoid
{
    static constexpr bool value = std::conjunction_v<std::is_invocable<Function, int>, std::is_void<std::invoke_result_t<Function, int>>>;
};

int main()
{
    auto l1 = [](auto x) {};
    std::cout << oneArgVoid<decltype(l1)>::value << "\n";
    auto l2 = [](auto x) {return 1; };
    std::cout << oneArgVoid<decltype(l2)>::value << "\n";
    auto l3 = [](auto x, auto y) {};
    std::cout << oneArgVoid<decltype(l3)>::value << "\n";
    return 0;
}

请注意,如果 oneArgVoid l3 上不调用>。实时演示: https://godbolt.org/z/8BUfpT

Note that if oneArgVoid is not called on l3 the code compiles. Live demo: https://godbolt.org/z/8BUfpT

我不使用boost,所以不能使用 mpl :: eval_if 。但是我认为 std :: conjunction 应该在这里短路,对吗?

I do not use boost, so I cannot use mpl::eval_if. But I thought that std::conjunction was supposed to short circuit here, am I wrong?

考虑到HolyBlackCat的建议,这甚至是一个陌生人: https://godbolt.org/z/2SUij-

Considering HolyBlackCat's suggestion, here's something even stranger: https://godbolt.org/z/2SUij-

推荐答案

std :: conjunction 似乎仅在的值上短路类型,类型本身仍然必须格式正确。因此,在这里, std :: is_void< std :: invoke_result_t< Function,int>> 实际上是非法的。由于进行了修改,因此:

It seems like std::conjunction short-circuits only on the values of the types, the types themselves still have to be well-formed. So this: std::is_void<std::invoke_result_t<Function, int>> is actually rightfully illegal here. Due to that with the modification:

template<typename Function>
struct argVoid
{
    static constexpr bool value = std::is_void_v<std::invoke_result_t<Function, int>>;
};

template<typename Function>
struct oneArgVoid
{
    static constexpr bool value = std::conjunction_v<std::is_invocable<Function, int>, argVoid<Function>>;
};

它可以工作,因为格式错误的表达式现在位于value变量中,这意味着它不会不会因为短路而得到评估。

It works, since the ill-formed expression is now in the value variable, which means it doesn't get evaluated due to the short-circuit.

这篇关于接合模板不会短路的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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