У меня есть вектор векторов, и я хочу проверить, все ли они пусты.Используя стандартную библиотеку, я попытался:
#include <algorithm>
#include <vector>
int main()
{
std::vector<std::vector<int>> vv;
std::all_of(std::begin(vv), std::end(vv), std::empty);
}
Это привело к следующей ошибке в clang 7.0:
/ 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 из транка, ни MSVC 2017 не смогли его скомпилировать:
https://godbolt.org/g/819pbQ (Clang)
https://godbolt.org/g/ua5E8e (MSVC)
EDIT2: Судя по всему, Роберт Анджейюк тоже прав: причина, по которой компилятор не может справиться с этим, - неоднозначное разрешение перегрузки.std :: empty имеет 3 разных перегрузки.и два из них являются одинаково хорошими кандидатами: общий и список std :: initializer один.Я достиг аналогичных результатов со следующей минимальной версией:
#include <vector>
template<class T>
void foo(const T& t);
template<class T>
void foo(const std::initializer_list<T>& il);
template<class F>
void bar(F f);
int main()
{
bar(foo<std::vector<int>>);
}
Однако есть одно отличие.Этот пример просто не компилируется в GCC из транка (вместо того, чтобы вызывать ICE).