如何使用概念在 C++ 20 中提供默认实现?

Deu*_*hie 5 c++ oop interface c++-concepts c++20

我正在试验使用conceptC++20 中引入的 s 作为静态接口的可能性。到目前为止,我做得很好,只是我无法找到一种为概念提供“默认实现”的方法。

例如,我有一个名为 的概念ByteBuffer,它是这样表述的:

template <typename T>
concept ByteBuffer = requires (T t) {
  { t.read_byte() } noexcept -> std::convertible_to<uint8_t>;
  { t.has_byte() } noexcept -> std::same_as<bool>;

  /* default implementation for `t.read_until(...)`? */
};
Run Code Online (Sandbox Code Playgroud)

从逻辑上讲,我应该能够为t.read_until(...)(省略参数)提供默认实现,并允许具体实现覆盖默认实现。有办法吗?我该怎么做?

如果这是不可能的,我认为添加这样的能力是合理的。

目前,我不得不求助于 CRTP 来提供一个外观类,我认为它比我想象的更加多余。

Nic*_*las 8

概念不是基类。事实上,概念与其任何模板参数都没有显式或隐式关系。

概念只做一件事:验证特定模板参数集是否适合在实例化特定模板时使用。仅此而已

概念包含一系列表达式和术语,它们应该对给定的模板参数有效。这就是确定一组模板参数对于特定用途是否有效所需的全部内容,这就是所有概念提供的内容。

如果您需要某种默认功能,则必须使用替代的 C++ 机制来做到这一点。最简单的是一个有自己约束的效用函数:

template<typename T>
concept ByteBufferReadUntil = ByteBuffer<T> &&
  requires(T bb) //Add parameters as appropriate
  {
    { t.read_until() } noexcept -> std::same_as<bool>;
  };

template<ByteBuffer T>
  requires ByteBufferReadUntil<T>
bool read_byte_buffer_until(T &bb)
{
  return t.read_until();
}

template<ByteBuffer T>
bool read_byte_buffer_until(T &bb)
{
  //default implementation for `t.read_until(...)`
}
Run Code Online (Sandbox Code Playgroud)

所以每当你想read_until为一个任意的做的时候ByteBuffer,你就调用read_byte_buffer_until.


cig*_*ien 6

概念实际上只是对类型的约束,因此向概念添加“默认实现”是没有意义的。相反,您可以做的是为 提供默认实现read_until,并使用它,除非某些ByteBuffer类型提供了自己的实现。

首先,您可以编写一个单独的概念来检查read_until

template <typename T>
concept Readable = requires (T t) {
 { t.read_until() } noexcept -> std::same_as<void>;  // takes no arguments, and returns void for demonstration
};
Run Code Online (Sandbox Code Playgroud)

然后您可以为不提供此功能的类型提供默认实现:

template <typename T>
void read_until_impl(T t) {
   std::cout << "default implementation";
}

template <Readable T>
void read_until_impl(T t) {
    t.read_until();  // call provided member function
}
Run Code Online (Sandbox Code Playgroud)

然后一些使用ByteBuffer类型的函数可以像这样调用函数:

template <ByteBuffer T>
void use(T t) {
    read_until_impl(t);
}
Run Code Online (Sandbox Code Playgroud)

这是一个演示