неявное преобразование std :: ref в путаницу ссылок - PullRequest
0 голосов
/ 13 апреля 2020

Я знаю, что std :: ref (объект) создает std :: reference_wrapper (объект), и что std :: reference_wrapper имеет неявную функцию-член оператора преобразования типов

operator T&() const

и Я знаю, что это влияет на то, как я использую его, когда в игру вступает вывод параметров шаблона: поэтому в Print ниже тип T аргумента выводится как std :: reference_wrapper, если я вызываю его, скажем, std :: ref ("hello ")

template <class T>
void Print(T t)
{
    std::cout << t << std::end;
}

Почему эта строка не компилируется?

std::string s = "hello";
std::cout << std::reference_wrapper<std::string>(s) << std::endl;

конкретизированная специализация должна иметь функцию преобразования типа

operator std::string&() const

, так почему я использую справочную обертку, как это?

1 Ответ

1 голос
/ 13 апреля 2020

Перегрузка operator<<, которую вы пытаетесь использовать, имеет следующую форму (от cppreference.com ):

template <class CharT, class Traits, class Allocator>

std::basic_ostream<CharT, Traits>&
    operator<<(std::basic_ostream<CharT, Traits>& os,
               const std::basic_string<CharT, Traits, Allocator>& str);

Второй параметр функции содержит параметры шаблона и не является выводимым контекстом. Поэтому он должен вывести аргументы шаблона. Неявные преобразования не учитываются для вывода аргумента шаблона, и, поскольку std::reference_wrapper не является std::basic_string, вывод не будет выполнен. Неважно, можно ли std::reference_wrapper преобразовать в std::string (или ссылку на него).

И просто уточнить, std::string является псевдонимом для специализации std::basic_string<char, std::char_traits<char>, std::allocator<char>> из std::basic_string. std::basic_string может быть специализирован для любого типа символов, например, wchar_t (который имеет псевдоним std::wstring). Другие специализации просто не часто используются.

...