Почему экземпляры шаблонов не могут быть выведены в `std::reference_wrapper`?

Предположим, у меня есть некоторый объект типа T, и я хочу поместить его в обертку ссылок:

int a = 5, b = 7;

std::reference_wrapper p(a), q(b);   // or "auto p = std::ref(a)"

Теперь я могу легко сказать if (p , потому что обертка ссылок имеет преобразование к своему обернутому типу. Все счастливы, и я могу обрабатывать коллекцию ссылочных оберток так же, как и исходные объекты.

(Как показано в вопросе по ссылке ниже, это может быть полезным способом создания альтернативного представления существующей коллекции, которую можно перегруппировать по своему усмотрению без затрат на полную копию, а также сохранить целостность обновления с исходной коллекцией. )


Однако с некоторыми классами это не работает:

std::string s1 = "hello", s2 = "world";

std::reference_wrapper t1(s1), t2(s2);

return t1 < t2;  // ERROR

Моим обходным решением является определение предиката как в этом ответе*; но мой вопрос:

Почему и когда операторы могут применяться к оберткам ссылок и прозрачно использовать операторы обернутых типов? Почему это не работает для std::string? Как это связано с тем, что std::string является экземпляром шаблона?

*) Обновление: В свете ответов кажется, что использование std::less() является общим решением.

17
задан Deduplicator 21 October 2018 в 23:54
поделиться