LINUX.ORG.RU

Не срабатывает SFINAE при компиляции clang'ом.

 


1

2

Есть подобный код: http://ideone.com/ZfkpKi

G++ его компилирует без каких-либо проблем. Clang выдаёт следующую ошибку:

$ clang++ -stdlib=libc++ -std=c++11 -Wall -pedantic -Wextra test-sfinae.cpp 
test-sfinae.cpp:8:5: error: no member named 'Serialize' in 'std::__1::vector<std::__1::tuple<int>, std::__1::allocator<std::__1::tuple<int> > >'
                t.Serialize(*this);
                ~ ^
test-sfinae.cpp:50:4: note: in instantiation of function template specialization 'Stream::operator>><std::__1::vector<std::__1::tuple<int>,
      std::__1::allocator<std::__1::tuple<int> > > >' requested here
        s >> data;
          ^
1 error generated.

Как можно исправить эту ошибку?

★★★★★

Как можно исправить эту ошибку?

Использовать ещё одну перегрузку оператора >> для вектора, а не извращаться с особой уличной специализацией, которая наверняка не соответствует стандарту.

quiet_readonly ★★★★
()

Как можно исправить эту ошибку?

отрепортить баг

wota ★★
()
Ответ на: комментарий от quiet_readonly

Но она есть `template<class T> Stream& operator>>(Stream& stream, std::vector<T>& vec)`, и именно она не хочет подставляться.

O02eg ★★★★★
() автор топика
Ответ на: комментарий от O02eg

Но она есть `template<class T> Stream& operator>>(Stream& stream, std::vector<T>& vec)`, и именно она не хочет подставляться.

Ну так я и сказал, надо использовать нормальную перегрузку вместо извращённой специализации.

quiet_readonly ★★★★
()
Ответ на: комментарий от O02eg

Если переместить эту функцию внутрь объявления Stream и при этом объявить её как friend вроде работает.

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

xaizek ★★★★★
()
Ответ на: комментарий от O02eg

Нет, так как он объявлен как friend и фактически попадает в область видимости, объемлюющую объявление класса. Это позволяет разрулить какую-то специальную ситуацию с разрешением имён. Все подробности по этому вопросу на память, к сожалению, не помню.

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

xaizek ★★★★★
()

Вытащил operator>> из класса, стало компилироваться и в clang'е.

O02eg ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.