Захватить дескриптор по ссылке или по значению в шаблоне класса ctor - PullRequest
0 голосов
/ 02 апреля 2020

Рассмотрим временный класс 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 Ответ

0 голосов
/ 02 апреля 2020

Этот класс не так хорош, как по моему мнению - вы предполагаете, что для "source" требуется m_read_ptr, m_last_valid и m_data в качестве контекста. Однако, если это, например, файл, он не требует ни одного из них. Вместо этого переписайте этот класс как интерфейс или, что еще лучше, вообще не создавайте обобщенный класс c и не используйте шаблоны при обработке «источников», например, в псевдокоде:

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);
}
...