简体   繁体   English

为什么成员 function 不能要求同一个 class 的 static constexpr 成员为真?

[英]Why can't a member function require a static constexpr member of the same class to be true?

I try to have a member function require a static constexpr boolean member to be true.我尝试让一个成员 function 需要一个 static constexpr boolean 成员为真。 This would be very helpful to DRY a quite complex requirement.这对于 DRY 一个相当复杂的需求非常有帮助。 And I do not quire get the reason why the compiler won't let me.而且我不需要知道编译器不允许我这样做的原因。

Minimal example with slightly less complex requirement:要求稍微不那么复杂的最小示例:

template <typename T>
struct Foo
{
    static constexpr bool isInt = std::integral<T>;
    void bar() requires (isInt);
    void goo() requires std::integral<T>;
};

template <typename T>
void Foo<T>::bar() requires (Foo<T>::isInt) // error: out-of-line definition of 'bar' does not match any declaration in 'Foo<T>' x86-64 clang 14.0.0 #1
{
    // ...
}

template <typename T>
void Foo<T>::goo() requires std::integral<T> // ok
{
    // ...
}

Is this because isInt is declared inside the same class?这是因为在同一个isInt中声明了 isInt 吗? Or do I have some kind of syntax error?还是我有某种语法错误?

There is a question of whether or not your requires clauses in the in-class declaration and out-of-class definition are equivalent (or functionally equivalent ).类内声明和类外定义中的requires子句是否等效(或功能等效)存在一个问题。

But regardless of the answer to that question, the easiest solution is to simply use the exact same token sequence, which will be certain to be equivalent:但不管这个问题的答案如何,最简单的解决方案是简单地使用完全相同的标记序列,这肯定是等价的:

template <typename T>
void Foo<T>::bar() requires (isInt)
{
    // ...
}

However, current Clang releases don't accept any variations I try to name the static member, especially not those using the same token sequence in both declaration and definition.但是,当前的 Clang 版本不接受我尝试命名 static 成员的任何变体,尤其是那些在声明和定义中使用相同标记序列的变体。 At least that last part is definitively a bug.至少最后一部分绝对是一个错误。

But on current Clang trunk all variations are accepted, indicating that this is a recently fixed bug.但在当前的 Clang 主干上,所有变体都被接受,表明这是最近修复的错误。

Seems like an MSVC bug.似乎是一个 MSVC 错误。 Here's a workaround:这是一个解决方法:

#include <concepts>

template <class T>
concept isInt = std::integral<T>;

template <typename T>
struct Foo
{
    void bar() requires (isInt<T>);
};

template <typename T>
void Foo<T>::bar() requires (isInt<T>) 
{
}

https://godbolt.org/z/h6enoGqG6 https://godbolt.org/z/h6enoGqG6

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

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