C++ 概念 - 我可以有一个要求在类中存在函数的约束吗?

use*_*764 8 c++ template-meta-programming c++-concepts

我在下面有一个简单的代码片段,它使用以下编译:

g++-9 -std=c++2a -fconcepts

这是试图定义一个需要函数存在的概念。我希望输出是“是”,但它不是......知道为什么吗?谢谢。

#include <iostream>


template <typename T>
concept bool HasFunc1 = 
    requires(T) {
        { T::func1() } -> int;
    };

struct Test
{
    int func1()
    {
        return 5;
    }
};

int main()
{
    if constexpr (HasFunc1<Test>)
        std::cout << "yes\n";
}
Run Code Online (Sandbox Code Playgroud)

yur*_*hek 9

您正在测试静态成员函数的存在。你想要的是

template <typename T>
concept bool HasFunc1 = 
  requires(T t) {
      { t.func1() } -> int;
  };
Run Code Online (Sandbox Code Playgroud)


Rob*_*ies 9

@makogan 问道(埋藏在评论中的 19 深处):如果 func 有参数怎么办?

答案是:对于简单的情况,使用构造函数或new表达式来制造参数。(不是特别可读,但比下面给出的可能正确的方法更具可读性)。

template <typename T>
concept HasFunc1 = 
  requires(T t) {
      { t.func1( int() ) } -> std::same_as<int>;
  };
Run Code Online (Sandbox Code Playgroud)

对于更复杂的示例,您可以在requires子句参数列表中声明测试参数:

concept IsCoServiceImplementation = requires(
    T t,
    CoServiceReply<typename T::return_type> *completionCallback)
{
    { T::return_type };
    {t.OnSuspend(completionCallback) };
    {t.OnCancel(completionCallback)  };
};
Run Code Online (Sandbox Code Playgroud)

这个概念确实具有预期的意图(对我来说):它主要将有关无法满足模板契约的嵌套 10 层深度的错误消息转换为几乎可读的第一级错误消息。

所需的代码和概念之间仍然存在奇怪的脱节。对参数类型有更严格的限制真是太好了。测试常量性是极其困难的。与我所希望的功能相去甚远。:-(

我仍在为 c++20 功能而苦苦挣扎。我愿意接受有关如何做得更好的建议。

(如果您想知道的话,CoService 是我正在进行的一项实验性尝试,目的是使将协程代码编组回非协程代码变得更加容易,同时将麻烦和麻烦降到最低)。


Que*_*tin 6

尝试自己调用它:

Test::func1();
Run Code Online (Sandbox Code Playgroud)

prog.cc: In function 'int main()':
prog.cc:19:14: error: cannot call member function 'int Test::func1()' without object
   19 |  Test::func1();
      |              ^
Run Code Online (Sandbox Code Playgroud)

啊对。func1应该是一个static成员函数,或者您应该在概念内的实例上调用它:

template <typename T>
concept bool HasFunc1 = 
    requires(T t) {
        { t.func1() } -> int;
    };
Run Code Online (Sandbox Code Playgroud)