Используйте std :: reference_wrapper < const T > для обработки констант T & amp; в конструкторе - уместно?

Если вы хотите узнать подробности, вы должны взглянуть на objects.h (особенно комментарии в верхней части файла). Ваш ctypes.c_byte(1) является объектом Python:

>>> import sys
>>> import ctypes
>>> isinstance(ctypes.c_byte(1), object)
True

Как отмечено @Daniel, sys.getsizeof получает размер этого объекта Python. Этот объект Python больше, чем соответствующий объект в C. Обратите внимание на следующее из комментариев object.h:

Objects are structures allocated on the heap. . . .
The actual memory allocated for an object
contains other data that can only be accessed after casting the pointer
to a pointer to a longer structure type.  This longer type must start
with the reference count and type fields; the macro PyObject_HEAD should be
used for this.

Другими словами, макрос PyObject_HEAD прикреплен к началу каждого объекта. Это увеличивает размер объекта Python.

ctypes.sizeof, с другой стороны, возвращает фактический размер типа данных C, который находится внутри объекта Python (с использованием оператора C sizeof), .

EDIT

В свете вашей цели, которую вы упомянули в своем комментарии к сообщению Даниэля, можно отправить один байт через сервер в Python 3.x. Ниже приведен пример того, как вы должны отправить байт, используя модуль socket Python, чтобы доказать эту точку.

Вот сервер, который вы будете запускать в одном интерпретаторе Python:

# Server
import socket

HOST = ''                      # All available interfaces
PORT = 50007                   # Same port as client
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print('Connected by', addr)
while True:
    data = conn.recv(1)        # receive data with bufsize 1; a larger bufsize will break this code
    if not data: break
    conn.sendall(data)
conn.close()

Вот клиент, который вы будете запускать в другом интерпретаторе python:

# Client
import socket

HOST = '127.0.0.1'             # The remote host, but here using localhost
PORT = 50007                   # The port used by both the client and server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'1')                # a bytes object
data = s.recv(1)               # Receive data from the socket with bufsize of 1
s.close()
print('Received', repr(data))  # confirm receipt

0
задан JFFIGK 16 January 2019 в 13:29
поделиться

2 ответа

Одной из основных проблем вашего интерфейса является то, что единственный конструктор T занимает const U&. Это означает, что вы можете передать временное значение в T и оставить reference_wrapper для мертвого объекта, поскольку const& в объекте не продлевает время жизни временного объекта.

Чтобы решить эту проблему, вам нужно добавить удаленный конструктор, который останавливает вас от принятия временных. Добавление

T(const U&&) = delete;

сделает это.

0
ответ дан NathanOliver 16 January 2019 в 13:29
поделиться

Это должно делать то, что вы хотите. Он использует std::reference_wrapper<T> так, как это было задумано (передача ссылок таким способом, который делает их копируемыми и назначаемыми). Я не вижу в этом ничего плохого. Из cppreference.com :

std :: reference_wrapper - это шаблон класса, который оборачивает ссылку в копируемый, назначаемый объект. Он часто используется как механизм для хранения ссылок внутри стандартных контейнеров (например, std :: vector), которые обычно не могут содержать ссылки.

Единственный потенциальный недостаток, который я вижу, это то, что std::reference_wrapper<T> может быть немного неудобным для использования и незнакомым для некоторых. Более распространенным решением вашей проблемы, вероятно, было бы просто сохранить указатель в вашем объекте вместо ссылки. Например:

class T {
private:
    const U* _u;

public:
    T(const U& u)
        : _u(&u) {}
    …
};
0
ответ дан Michael Kenzel 16 January 2019 в 13:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: