Когда я пытаюсь запустить следующий код, и clang (6.0), и g ++ (8) с -std = c ++ 17 выдают ошибку static_assert:
#include <set>
struct A {};
struct ProcessComparator { inline bool operator()(const A&, const A&) { return true; } };
int main(void)
{
std::set<A, ProcessComparator> A_Set;
return EXIT_SUCCESS;
}
г ++ 8
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_tree.h:457:7: ошибка: Сбой static_assert из-за требования is_invocable_v «объект сравнения должен быть вызван как const»
лязг 6.0
/usr/include/c++/8/bits/stl_tree.h:457:21: ошибка: статическое утверждение не удалось: объект сравнения должен быть вызван как const
Помещение const в качестве части подписи operator () устраняет эту проблему:
#include <set>
struct A {};
/* Add const as part of the operator's signature */
struct ProcessComparator { inline bool operator()(const A&, const A&) const { return true; } };
int main(void)
{
std::set<A, ProcessComparator> A_Set;
return EXIT_SUCCESS;
}
Между тем при std = c ++ 14 ошибка исчезает как в clang, так и в g ++.
Мой вопрос: что изменилось в c ++ 17 для того, чтобы теперь выдавать ошибку, и почему здесь имеет значение const?
Const только гарантирует, что каждый объект, объявленный внутри класса ProcessComparator, не будет изменен (кроме объектов с изменяемым), так почему это требование?
Это исходный код из исходного кода, где статическое утверждение не выполняется:
#if __cplusplus >= 201103L
static_assert(__is_invocable<_Compare&, const _Key&, const _Key&>{},
"comparison object must be invocable with two arguments of key type");
# if __cplusplus >= 201703L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2542. Missing const requirements for associative containers
static_assert(is_invocable_v<const _Compare&, const _Key&, const _Key&>,
"comparison object must be invocable as const");
# endif // C++17
#endif // C++11
Был добавлен новый static_assert, где объект сравнения был изменен с _Compare&<
в const _Compare&
а также is_invocable
в is_invocable_v
Хотя это, насколько я могу понять, это просто получить inline и constexpr как видно здесь
я обнаружил этот ссылка, основанная на комментарии исходного кода, но я до сих пор не могу понять Зачем это обязательно.
Задача ещё не решена.
Других решений пока нет …