【问题标题】:How do you declare a generic type of an expression in a `requires` constraint?如何在 `requires` 约束中声明表达式的泛型类型?
【发布时间】:2021-09-16 19:26:53
【问题描述】:

我可能在这里问了一个错误的问题,但我到底做错了什么,它导致编译器认为我期望堆栈的 pop 方法的约束是std::same_as<void, T>

#include <concepts>
#include <stack>

template <typename S, typename T>
concept generic_stack = requires(S s, T t) {
    s.push(t);
    { s.pop() } -> std::same_as<T>; // error seems to stem from here
};

template <typename T, generic_stack<T> S>
void compile_if_stack(S) {}

int main() {
    compile_if_stack<int>(std::stack<int>{});
}

我尝试了std::same_as&lt;decltype(s.pop()), T&gt;;,它似乎有效,但我不明白前一种方法有什么问题。

完全错误

# clang 12.0.1
$ clang++ -std=c++20 main.cpp
main.cpp:14:5: error: no matching function for call to 'compile_if_stack'
    compile_if_stack<int>(std::stack<int>{});
    ^~~~~~~~~~~~~~~~~~~~~
main.cpp:11:6: note: candidate template ignored: constraints not satisfied [with T = int, S = std::stack<int>]
void compile_if_stack(S) {}
     ^
main.cpp:10:23: note: because 'generic_stack<std::stack<int>, int>' evaluated to false
template <typename T, generic_stack<T> S>
                      ^
main.cpp:7:25: note: because type constraint 'std::same_as<void, int>' was not satisfied:
    { s.pop() } -> std::same_as<T>; // error seems to stem from here
                        ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../include/c++/11.1.0/concepts:63:19: note: because '__detail::__same_as<void, int>' evaluated to false
      = __detail::__same_as<_Tp, _Up> && __detail::__same_as<_Up, _Tp>;
                  ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../include/c++/11.1.0/concepts:57:27: note: because 'std::is_same_v<void, int>' evaluated to false
      concept __same_as = std::is_same_v<_Tp, _Up>;
                          ^
1 error generated.

来自GCC 11.1.0 的 C++ 编译器出现语义相同的错误消息。

【问题讨论】:

    标签: c++ templates c++20 c++-concepts


    【解决方案1】:

    这是因为 stack.pop() 返回 void,如 std::stack::pop 中所述。

    约束不正确,你应该检查top

    template <typename S, typename T>
    concept generic_stack = requires(S s, T t) {
        s.push(t);
        { s.top() } -> std::same_as<T const&>;
    };
    

    【讨论】:

    • 我的错,我刚刚浏览了std::stack。所以真正的问题是我对堆栈的想法与 STL 不兼容,当我意识到这一点时,这个错误确实是有道理的......谢谢。
    【解决方案2】:

    std::stack 不会在 pop 上返回值。它有一个单独的功能。即top。所以pop() 是一个void 函数。因此出现错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 2022-10-06
      相关资源
      最近更新 更多