enable_if с типом возврата для функции-члена класса - PullRequest
0 голосов
/ 16 февраля 2019

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

Поскольку двапараметры шаблона не могут быть необязательными, а аргумент enable_if не одобряется в рекомендациях, поэтому я опробовал (оставшиеся) следующие 2 способа:

template <bool boolean = true>
struct sample {
    constexpr typename std::enable_if<boolean, int>::type bool_check_return(
        int s) const noexcept {
        return s + 1;
    }
    constexpr typename std::enable_if<!boolean, int>::type bool_check_return(
        int s) const noexcept {
        return s;
    }

    template <typename std::enable_if<boolean, int>::type = 0>
    int bool_check_template(
        int s) const noexcept {
        return s + 1;
    }
    template <typename std::enable_if<!boolean, int>::type = 0>
    int bool_check_template(
        int s) const noexcept {
        return s;
    }
};

ссылка Godbolt

На первый взгляд, мне не кажется очевидным, почему возвращаемый тип SFINAE выдает следующую ошибку о том, что «перегрузка не применима к функциям, отличающимся только типом возврата».SFINAE должен был обеспечить только одну копию, а не две.

Какую часть стандарта я неосознанно нарушаю?Или это ошибка компилятора?Практически, это не было бы проблемой в C ++ 17 с if constexpr (и поскольку одна форма работает, я могу просто выбрать эту).

Эта ошибка присутствует в C ++ 11 - C ++17, что дает малую вероятность того, что компиляторы ошибаются в этом.

error: functions that differ only in their return type cannot be overloaded
    constexpr typename std::enable_if<!boolean, int>::type bool_check_return(
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
note: previous definition is here
    constexpr typename std::enable_if<boolean, int>::type bool_check_return(
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
1 error generated.

Ответы [ 2 ]

0 голосов
/ 16 февраля 2019

Компилятор прав.В любом случае вы не можете перегрузить две функции с одним и тем же типом возврата, даже если после замены будет действительным только один тип возврата.

С [over.load] :

Некоторые объявления функций не могут быть перегружены:

  • Объявления функций, которые отличаются только типом возврата, спецификацией исключения или обеими, не могут быть перегружены.
  • ...

Нет исключений из этого правила.

0 голосов
/ 16 февраля 2019

Здесь СФИНА не участвует, потому что bool_check_return сами по себе не являются шаблонами.Это просто обычные перегруженные функции, которые отличаются только типом возврата.Создание их шаблонов решило бы проблему, разрешив только один из них:

template<bool enabled = boolean>
constexpr typename std::enable_if<enabled, int>::type bool_check_return(
    int s) const noexcept {
    return s + 1;
}

template<bool enabled = boolean>
constexpr typename std::enable_if<not enabled, int>::type bool_check_return(
    int s) const noexcept {
    return s;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...