Пустые угловые скобки в C ++ - PullRequest
3 голосов
/ 10 марта 2020

При изучении библиотеки Rx Cpp я обнаружил следующий пример, который я не могу интерпретировать.

    auto ints = rxcpp::observable<>::create(
        [](rxcpp::subscriber<int> s){
            s.on_next(1);
            s.on_next(2);
            s.on_completed();
    });

В библиотеке есть два объявления класса observable:

template<class T, class SourceOperator>
class observable
    : public observable_base<T>
{
// ...
};

template<>
class observable<void, void>
{
// ...
};

Я не смог понять, как компилятору удается принять rxcpp::observable<>. кусок. Могло быть много явных специализаций observable для разных типов, кроме void,void.

Вопрос в том, как компилятор интерпретирует пустые угловые скобки в этом коде: rxcpp::observable<>.

Я не вижу ни параметров шаблона по умолчанию в классе observable, ни параметров шаблона variadi c, которые могли бы это объяснить.

Затем я подумал, что это как-то связано с явной специализацией шаблона, и попытался воспроизвести его в изолированном виде. например, эта программа

namespace isolated {
  template<class T>
  class Test {
  public:
    static void say() {
      cout << "I am generic" << endl;
    }
  };

  template<>
  class Test<int> {
  public:
    static void say() {
      cout << "I am integer" << endl;
    }
  };
}

int main() {
  isolated::Test<>::say(); // ERROR: too few arguments for class template.....
}

Однако она не компилируется, хотя существует только одна явная специализация.

1 Ответ

5 голосов
/ 11 марта 2020

Вам не хватает:

template<
     class T = void,
     class SourceObservable = typename std::conditional<std::is_same<T, void>::value,
         void, dynamic_observable<T>>::type>
 class observable;

из строк 142-146 файла rx-priorf.hpp

Это прямое объявление предоставляет аргументы шаблона по умолчанию для observable класс и позволяет вам написать observable<>, который будет использовать эти значения по умолчанию. В вашем примере это будет достигнуто путем добавления

template<class T = int>
class Test;

, что дает вам

namespace isolated {
  template<class T = int>
  class Test;

  template<class T>
  class Test {
  public:
    static void say() {
      cout << "I am generic" << endl;
    }
  };

  template<>
  class Test<int> {
  public:
    static void say() {
      cout << "I am integer" << endl;
    }
  };
}

int main() {
  isolated::Test<>::say(); // ERROR: too few arguments for class template.....
}

и выводит

I am integer

в этом живом примере

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