Использование универсальных ссылок с нешаблонными типами?

Я создаю простой оператор конвейера для векторов, который пользователь будет использовать следующим образом (псевдокод):

      auto x = std::vector{1,2,3} | push_back(10)
                            | push_back(100)
                            ;

Теперь я попытался определить оператор трубопровода следующим образом:

      template <typename T>
constexpr inline auto& operator| (std::vector<T>&& vec, std::invocable<std::vector<T>> auto&& func);

Но теперь vec только для r-значений (поскольку тип самого vec не выводится)! Но я хочу, чтобы он также привязывался к l-значениям. Как мне это сделать?

Одним уродливым, но функциональным решением было бы сделать еще одну перегрузку для моего оператора трубопровода, но с std::vector<int>&. Однако это не масштабируется (2 ^ n перегрузок для n аргументов!), и я считаю, что это та самая причина, по которой были созданы универсальные ссылки.

Как я могу использовать универсальные ссылки в этом случае?

1 ответ

Конечно, вы можете использовать ссылки для переадресации.

      template <typename T> inline constexpr bool is_vector = false;
template <typename ...P> inline constexpr bool is_vector<std::vector<P...>> = true;

template <typename T> requires is_vector<std::remove_cvref_t<T>>
constexpr auto &operator|(T &&vec, std::invocable<T> auto &&func);

Кроме того, помните, что операторы обычно должны создаваться в том же пространстве имен, что и один из их параметров, чтобы ADL мог их найти. Но ты не можешь коснуться namespace std...

Кроме того, мне не нравится идея перегрузки оператора, при котором ни один из параметров не является классом, который вы создали. Если ваши пользователи не должны явно соглашаться на использование этих операторов, выполняя using namespace ...;.

Другие вопросы по тегам