Я только что получил ошибку компилятора для следующей конструкции:

size_t N = 10;
size_t Ntransforms = std::min(PySequence_Fast_GET_SIZE(__transforms), N);

Поскольку PySequence_Fast_GET_SIZE() фактически возвращает Py_ssize_t, а std::min() определяется как

template <class T> const T& min (const T& a, const T& b);

Поскольку он принимает ссылки lvalue одного и того же типа, я был удивлен, что смог исправить это с помощью встроенного преобразования типов:

size_t Ntransforms = std::min((size_t)PySequence_Fast_GET_SIZE(__transforms), N);

Это нормально? Если да, эквивалентен ли он явному коду:

size_t Ntransforms = PySequence_Fast_GET_SIZE(__transforms);
if (Ntransforms > N) Ntransforms = N;
c++
1
Stefan 28 Авг 2014 в 13:02
1
Предполагая, что PySequence_Fast_GET_SIZE никогда не возвращает отрицательное значение, вы также можете вместо этого указать явный тип шаблона, например std::min<size_t>, и полагаться на неявное преобразование. Хотя здесь это не имеет никакого значения, возможно, вы захотите избежать использования приведений в стиле c, но лучше привыкнуть вместо этого использовать static_cast.
 – 
user657267
28 Авг 2014 в 13:08
3
min принимает const lvalue references, поэтому они привязываются к временным
 – 
Piotr Skotnicki
28 Авг 2014 в 13:08
Странное соглашение об именах: PySequence_Fast_GET_SIZE.
 – 
Nawaz
28 Авг 2014 в 13:08
Да @PiotrS., забыл об этом!
 – 
Stefan
28 Авг 2014 в 13:09
1
Конечно странно, это Python ;-)
 – 
Angew is no longer proud of SO
28 Авг 2014 в 13:14

2 ответа

Лучший ответ

Подпись std::min заставляет аргументы одного и того же типа:

 template <class T> const T& min (const T& a, const T& b);

Вызов неоднозначен, если типы аргументов различаются.

Однако можно использовать временные значения (полученные, например, в результате выражения приведения) вместо аргументов, потому что std::min принимает const lvalue-ссылки.

В качестве альтернативы вы можете принудительно использовать тип, используемый для создания экземпляра std::min:

std::min<std::size_t>(PySequence_Fast_GET_SIZE(__transforms), N);
6
Piotr Skotnicki 27 Июн 2015 в 23:50
Спасибо! Мне особенно нравится версия с принудительным вводом текста, о которой я не знал.
 – 
Stefan
28 Авг 2014 в 13:16

Да, ты можешь. Тем не менее, он эквивалентен указанному вами варианту. Вы можете использовать форму:

size_t Ntransforms = std::min(static_cast<size_t>(PySequence_Fast_GET_SIZE(__transforms)), N);
0
Zorgiev 28 Авг 2014 в 13:14