Код: Выделить всё
#include
#include
int main()
{
std::vector vv;
std::all_of(std::begin(vv), std::end(vv), std::empty);
}
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/bits/stl_algo.h :508:5:
примечание: шаблон-кандидат игнорируется: не удалось вывести аргумент шаблона
'_Predicate'
Думаю, это стандартное поведение, обусловленное правилами вывода типов. Но в любом случае, какой самый простой способ обойти это?
РЕДАКТИРОВАТЬ: Я принял ответ Rubenvb, потому что он дал простое и разумное объяснение вместе с естественным обходным путем. all_of принимает предикат, который является функцией, объектом функции или лямбда-выражением. std::empty не является ни тем, ни другим, а шаблоном функции. При явном создании экземпляра мы получаем простую функцию, которая должна работать. Удивительно, но большинство компиляторов, которые я пробовал, по-прежнему не компилируются.
Ну, посмотрим:
на GCC 6.3 , он компилируется нормально - https://godbolt.org/g/Pxta7C
но в GCC из магистрали это вызывает внутреннюю ошибку компилятора - https://godbolt.org/g/H6DHt5
Ни Clang from Trunk, ни MSVC 2017 не смогут его скомпилировать:
https://godbolt.org/g/819pbQ (Clang)
https://godbolt.org/g/ua5E8e (MSVC)
EDIT2: Судя по всему, Роберт Анджеюк тоже прав: причина, по которой компилятор не может справиться с этим, заключается в неоднозначном разрешении перегрузки. std::empty имеет 3 разные перегрузки. и два из них одинаково хороши: общий и список std::initializer. Я добился аналогичных результатов со следующей минимальной версией:
Код: Выделить всё
#include
template
void foo(const T& t);
template
void foo(const std::initializer_list& il);
template
void bar(F f);
int main()
{
bar(foo);
}
Подробнее здесь: https://stackoverflow.com/questions/505 ... -predicate
Мобильная версия