2013-05-06 3 views
1

Учитывая следующий код: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, например), что позволило бы такое неявное преобразование?

+0

Независимо от причины, вы должны всегда разворачивать 'reference_wrapper's, если вы ожидаете их. – Xeo

+0

@Xeo Это совсем наоборот, я передаю reference_wrapper UnaryFunction в качестве параметра класса шаблона, который ожидает UnaryFunction. Точнее: 'typedef boost :: transform_iterator > iterator' ' typedef boost :: transform_iterator > const_iterator' и я ожидал бы 'iterator' быть _implicitely convertible_ в 'const_iterator'. –

+2

В C++ разные специализации одного и того же базового типа не связаны между собой, независимо от отношения, которое имеет тип экземпляра. 'std :: reference_wrapper ' больше не связан с 'std :: reference_wrapper ' чем 'std :: reference_wrapper '. Хотя вы можете * хотеть, чтобы они были конвертируемыми, я бы не сказал, что вы должны ожидать этого. –

ответ

0

Существует неявная автоконверсия между std::reference_wrapper и ее базовым типом (поскольку это может быть небезопасным и запутанным).

Правильный синтаксис должен быть:

std::reference_wrapper<const int> z = x.get(); 
+0

[Да, есть неявное преобразование из 'std :: reference_wrapper -> T &'.] (Http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/get) – Xeo

+0

@Xeo: делаем ли мы нужно это где-то в этом выражении: '' std :: reference_wrapper z = x; ''? –

Смежные вопросы