Учитывая следующий код:reference_wrapper и неявное преобразование
int v = 12;
std::reference_wrapper<int> x(v);
std::reference_wrapper<const int> y(x); // (1) This works
std::reference_wrapper<const int> z = x; // (2) This fails
, если я правильно понимаю, (1) работает, потому что она требует только один пользовательского преобразования, (2) терпит неудачу, потому что она включает в себя два пользовательских переходов в последовательность преобразования:
std::reference_wrapper<int>::operator int& and
std::reference_wrapper<const int>::(const int&)
Таким образом, std::reference_wrapper<int>
не неявно конвертируемым в std::reference_wrapper<const int>
, что нарушает часть моего кода, где я использую std::is_convertible
черту.
Есть ли какой-либо причине об этом проекте с участием не-присутствие общего конструктора копирования:
template <typename Y>
reference_wrapper<T>::reference_wrapper(const reference_wrapper<Y>&)
(так же, как в std::shared_ptr
, например), что позволило бы такое неявное преобразование?
Независимо от причины, вы должны всегда разворачивать 'reference_wrapper's, если вы ожидаете их. – Xeo
@Xeo Это совсем наоборот, я передаю reference_wrapper UnaryFunction в качестве параметра класса шаблона, который ожидает UnaryFunction. Точнее: 'typedef boost :: transform_iterator> iterator' ' typedef boost :: transform_iterator > const_iterator' и я ожидал бы 'iterator' быть _implicitely convertible_ в 'const_iterator'. –
В C++ разные специализации одного и того же базового типа не связаны между собой, независимо от отношения, которое имеет тип экземпляра. 'std :: reference_wrapper' больше не связан с 'std :: reference_wrapper ' чем 'std :: reference_wrapper '. Хотя вы можете * хотеть, чтобы они были конвертируемыми, я бы не сказал, что вы должны ожидать этого. –