简体   繁体   English

是否有 'void_t' 的 'requires' 替代品?

[英]Is there a 'requires' replacement for 'void_t'?

void_t is a nice hack to detect compilability of certain expressions, but I wonder if there is some way to do that check with requires (or requires requires ) since I really do not like void_t from the readability perspective. void_t是检测某些表达式的可编译性的好方法,但我想知道是否有某种方法可以使用requires (或 requires requires )进行检查,因为从可读性的角度来看我真的不喜欢void_t

For example, for a certain type I want to check if some expression is fine (ie compilable) or not, including negations.例如,对于某种类型,我想检查某些表达式是否正确(即可编译),包括否定。

Ideally I would wish that this works, but it does not, probably since lambdas are not templated...理想情况下,我希望这可行,但它不可行,可能是因为 lambda 没有模板化......

#include <unordered_set>


int main() {
    auto a = []() requires requires(int x) {x<x;} {};
    auto b = []() requires !requires(std::unordered_set<int> x) {x<x;} {};
}

If this use seems weird, my real motivation is to check that something does not compile, for example that my nontemplated type does not have operator< or that it is not constructible from int or...如果这种用法看起来很奇怪,我的真正动机是检查某些东西是否无法编译,例如我的非模板化类型没有operator<或者它不能从int或......

PS: I know boost::hana has a way to do this , I am looking for vanilla C++20 solution. PS:我知道boost::hana办法做到这一点,我正在寻找香草 C++20 解决方案。

my real motivation is to check that something does not compile, for example that my nontemplated type does not have operator <我真正的动机是检查某些东西没有编译,例如我的非模板化类型没有operator <

This is possible with concepts, perhaps I am misunderstanding?这在概念上是可能的,也许我误解了?

template<class T>
concept has_less_than = requires(const T& x, const T& y)
{
   {x < y} -> std::same_as<bool>;
};

struct Has_Less
{
    bool operator<(const Has_Less& other) const
    {
        return true;
    }
};

struct Nope{};

int main()
{
    static_assert(has_less_than<Has_Less>);
    static_assert(!has_less_than<Nope>);
}

Live Demo现场演示

While the answer of @AndyG is perfectly fine, I would like to make an addition.虽然@AndyG 的回答非常好,但我想补充一点。 You can make an ad-hoc concept as well, like you can see in the next example program (includes are missing):您也可以创建一个临时概念,就像您在下一个示例程序中看到的那样(缺少包含):

void func( auto v )
{
    // unnamed concept in constexpr if-branch!
    if constexpr( requires { { v < v }->std::same_as<bool>; } ) {
        // use operator
        puts( "HAVE operator <" );
    } else {
        // cannot use operator
        puts( "no operator <" );
    }
}

struct X {};

int main()
{
    func( 2 );
    func( X{} );
    return EXIT_SUCCESS;
}

Tested with VisualStudio 2022 (17.3.5) in C++20 mode.在 C++20 模式下使用 VisualStudio 2022 (17.3.5) 进行测试。

This technique is named "Design by introspection".这种技术被命名为“内省设计”。 I also recently wrote a short blog post to this (can be found in my profile).我最近还为此写了一篇简短的博客文章(可以在我的个人资料中找到)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM