свернуть выражение и поиск имени функции - PullRequest
4 голосов
/ 17 июня 2020

Я изучаю складные выражения на C ++ 17. У меня есть следующий код

#include <iostream>
#include <vector>

namespace io {
template<typename T>
std::istream &operator>>(std::istream &in, std::vector<T> &vec) {
  for (auto &x : vec)
    in >> x;
  return in;
}

template<class... Args> void scan(Args &... args) {
  (std::cin >> ... >> args);
}
}// namespace io

int main() {
    std::vector<int> s(1), t(1);
    io::scan(s, t);
    std::cout << s[0] << ' ' << t[0] << '\n';
}

Используя G CC 9.3.0 , код компилируется и работает правильно, но с использованием Clang 10.0.0 тот же код не компилируется:

<source>:13:16: error: call to function 'operator>>' that is neither visible in the template definition nor found by argument-dependent lookup
  (std::cin >> ... >> args);
               ^
<source>:19:9: note: in instantiation of function template specialization 'io::scan<std::vector<int, std::allocator<int> >, std::vector<int, std::allocator<int> > >' requested here
    io::scan(s, t);
        ^
<source>:6:15: note: 'operator>>' should be declared prior to the call site
std::istream &operator>>(std::istream &in, std::vector<T> &vec) {
              ^
1 error generated.

Почему clang повторно генерирует код, но g cc принимает его?

1 Ответ

1 голос
/ 25 августа 2020

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

I исправил это относительно недавно (к сожалению, не вовремя для предстоящего выпуска Clang 11), и теперь тестовый пример принимается магистралью Clang .

...