Двухэтапный поиск оператора < - PullRequest
0 голосов
/ 30 мая 2018

В настоящее время я пытаюсь перегрузить оператор вставки << для класса, над которым я работал.По какой-то причине я разделил его на две функции и вызвал одну из другой.После перехода на шаблоны он больше не работал.После поиска проблемы я узнал о двухэтапном поиске и некоторых рассуждениях .

По сути, я пытался сделать следующее:

template <typename Foo, typename Bar>
class MyClass {
public:
  using foo_t = Foo;
  using bar_t = Bar;

  bar_t some_func() const { /* do something */ }
};

/* Level 2 operator */
template <typename Foo, typename Bar>
std::ostream& operator<<(std::ostream& out, const typename MyClass<Foo,Bar>::bar_t& bar) {
  return out << some_other_func(bar);
}

/* Level 1 operator calls level 2 operator */
template <typename Foo, typename Bar>
std::ostream& operator<<(std::ostream& out, const MyClass<Foo,Bar>& myClass) {
  return out << myClass.some_func();
}

К сожалению, из-за того, что bar_t зависит, это не компилируется, что заставило меня изменить оператор уровня 1 на следующее:

template <typename Foo, typename Bar>
std::ostream& operator<<(std::ostream& out, const MyClass<Foo,Bar>& myClass) {
  return operator<<<Foo,Bar>(out,myClass.some_func());
}

Теперь это возможноне очень красиво и, на мой взгляд, стирает цель оператора <<.

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

1 Ответ

0 голосов
/ 30 мая 2018

Проблема, которую вы описываете, не имеет ничего общего с двухэтапным поиском.Вместо этого это связано с тем, что в функции

template <typename Foo, typename Bar>
std::ostream& operator<<(std::ostream& out, const typename MyClass<Foo,Bar>::bar_t& bar)

Foo и Bar находятся в не выводимом контексте.Это означает, что вы должны предоставлять эти аргументы шаблона каждый раз, когда вызываете функцию.

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

template<class T> struct A {
    using type = int;
    type i = 42;
};

template<class T> void foo(typename A<T>::type );
...
A<void*> a;
foo(a.i); // problematic call

Вы хотите, чтобы T выводился в void* в примере выше.Тем не менее, тип a.i является int.Таким образом, этот вызов идентичен

foo(int(42));

Очевидно, что здесь нет никакого значимого компилятора T, который мог бы вывести здесь.типы с потоками.Если вы не можете, то, вероятно, операторы вставки потоков не подходят для этого, так как синтаксис действительно ужасен.Просто используйте нормальные функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...