通过引用或值捕获句柄到类模板ctor
Posted
技术标签:
【中文标题】通过引用或值捕获句柄到类模板ctor【英文标题】:Capture handle by reference or by value to class template ctor 【发布时间】:2020-07-14 21:06:17 【问题描述】:考虑一个模板类InputBuffer
:
template<class Source, size_t Capacity>
class InputBuffer
public:
explicit InputBuffer(Source src);
int getchar();
private:
std::byte const* m_read_ptr;
std::byte const* m_last_valid;
Source m_src;
std::array<std::byte, Capacity> m_data;
void fetchAndResetPointers();
;
问题:构造函数是否应该接受src
作为引用并存储指针而不是按值获取? 非常调用者在这里期望引用语义。但是,也有可能Source
已经是某种指针,然后,通过引用获取src
并存储指针会导致不必要的间接。如果不通过引用传递,用户可以根据需要使用std::ref
。
【问题讨论】:
【参考方案1】:在我看来,这个类并不好 - 你假设“源”需要 m_read_ptr
、m_last_valid
和 m_data
作为上下文。但是,如果它是一个文件,例如,它不需要这些。相反,将此类重写为接口,或者更好的是,根本不创建泛型类并在处理“源”时使用模板,例如伪代码:
class FileBuffer
public:
explicit FileBuffer(File* f) : m_f(f)
int getchar() return read(f, 1);
private:
File* m_f;
;
template<class T>
void print_from_buffer_to_stdout(T& buf)
std:: cout << buf.getchar();
int main()
FileBuffer f = get_file_buffer(); // somehow
print_from_buffer_to_stdout(f);
【讨论】:
其实m_read_ptr
会指向本地缓冲区数组,fetchAndResetPointers
会在buffer
为空时调用(m_read_ptr == m_last_valid
)。您的建议不是缓冲区:它依赖于 File
在内部提供缓冲区。使用 InputBuffer 的原因是调用 read
可能会产生很大的开销,因此您通常调用 read 来获取多个字节,例如一整页。
你没有抓住重点——“inputbuffer”类不应该包含“Source”作为其成员,或者不包含所有其他成员/方法。
抱歉,您确实需要了解如何实现缓冲 I/O。输入缓冲区的实现至少需要知道它的来源,如果它不是 getchar 的参数的话。但它不能作为 getchar 的参数,因为这会引入不一致。以上是关于通过引用或值捕获句柄到类模板ctor的主要内容,如果未能解决你的问题,请参考以下文章