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 来提供一个外观类,我认为它比我想象的更加多余。
概念不是基类。事实上,概念与其任何模板参数都没有显式或隐式关系。
概念只做一件事:验证特定模板参数集是否适合在实例化特定模板时使用。仅此而已。
概念包含一系列表达式和术语,它们应该对给定的模板参数有效。这就是确定一组模板参数对于特定用途是否有效所需的全部内容,这就是所有概念提供的内容。
如果您需要某种默认功能,则必须使用替代的 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.
概念实际上只是对类型的约束,因此向概念添加“默认实现”是没有意义的。相反,您可以做的是为 提供默认实现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)
这是一个演示。