Информация об изменениях

Сообщение Re[3]: Создать новый std::tuple из подмножества имеющегося от 22.02.2023 12:46

Изменено 22.02.2023 13:15 rg45

Re[3]: Создать новый std::tuple из подмножества имеющегося
Здравствуйте, SaZ, Вы писали:

SaZ>Спасибо, то что надо, но я никак не могу осилить enable_if:


SaZ>
SaZ>// template <typename T, std::enable_if_t<std::is_convertible_v<T*, my_base *>, bool> = true>
SaZ>// template <typename T, typename = std::enable_if_t<std::is_base_of_v<my_base, T>, bool>>
SaZ>template <typename T, std::enable_if_t<std::is_base_of_v<my_base, T>, bool> = true>
SaZ>auto my_filter(const T& v)
SaZ>{
SaZ>    return std::make_tuple(v);
SaZ>}
SaZ>


SaZ>Эта перегрузка никогда не вызывается. Хотя пробовал static_assert вне этой функции — всё ок.


Сама по себе функция написана правильно. Не вызываться она может по разным причинам:

  • Возможно, эта функция определена не в том пространстве имен, в котором нужно, и не находится при ADL;
  • Возможно, существуют какие-то другие одноименные перегрузки, которые выигрывают overload resolution. Например, если в этой же области видимости определена перегрузка my_filter(T&& v), то она будет выигрывать подстановку для rvalue и неконстантных lvalue выражений (неконстантных объектов, проще говоря), использованных в качестве фактических параметров.
  • Для функций, у которых тип результата объявлен как auto, содержитомого тела функции должно быть достаточно для того, чтоб компилятор мог вывести тип возвращаемого значения. Если, например, в точке инстанцирования тип T, или тип базового класса my_base не являются полными (не подключены заголовки с определениями классов), то эта функция молча скипнется по принципу "Substitution Failure Is Not An Error" (SFINAE).

Чтоб диагностировать точно, желательно видеть минимальный пример, воспроиводящий проблему.
Re[3]: Создать новый std::tuple из подмножества имеющегося
Здравствуйте, SaZ, Вы писали:

SaZ>Спасибо, то что надо, но я никак не могу осилить enable_if:


SaZ>
SaZ>// template <typename T, std::enable_if_t<std::is_convertible_v<T*, my_base *>, bool> = true>
SaZ>// template <typename T, typename = std::enable_if_t<std::is_base_of_v<my_base, T>, bool>>
SaZ>template <typename T, std::enable_if_t<std::is_base_of_v<my_base, T>, bool> = true>
SaZ>auto my_filter(const T& v)
SaZ>{
SaZ>    return std::make_tuple(v);
SaZ>}
SaZ>


SaZ>Эта перегрузка никогда не вызывается. Хотя пробовал static_assert вне этой функции — всё ок.


Сама по себе функция написана правильно. Не вызываться она может по разным причинам:

  • Возможно, эта функция определена не в том пространстве имен, в котором нужно, и не находится при ADL;
  • Возможно, существуют какие-то другие одноименные перегрузки, которые выигрывают overload resolution. Например, если в этой же области видимости определена перегрузка my_filter(T&& v), то она будет выигрывать подстановку для rvalue и неконстантных lvalue выражений (неконстантных объектов, проще говоря), использованных в качестве фактических параметров.
  • Для функций, у которых тип результата объявлен как auto, содержитомого тела функции должно быть достаточно для того, чтоб компилятор мог вывести тип возвращаемого значения. Чтоб эта функция работала, неоходимо, чтоб оба типа — T и my_base были полными в точке инстанцирования (т.е. подключены заголовки с определениями этих классов).

Чтоб диагностировать точно, желательно видеть минимальный пример, воспроиводящий проблему.