Поведение условной функции на основе указателя типа шаблона

Я пытаюсь придумать функцию-член для класса шаблона, которая:

  • что-то делает, если тип шаблона является указателем
  • ничего не делает для указателей

Не уверен, применимо ли к этому SFINAE, поскольку мне нужны обе версии, поскольку я называю их в самом классе. Обратите внимание, я ограничен C++ 11.

template < typename T_ = T, typename = std::enable_if_t <!std::is_pointer<T_>{} > >
void SomeFunction()
{
    // Do nothing
}
template < typename T_ = T, typename = std::enable_if_t < std::is_pointer<T_>{} > >
void SomeFunction()
{
    // Do sth
}

Компилятор жалуется, что ошибка C2535: функция-член уже определена или объявлена.

stackoverflow.com/questions/53351945/…
llllllllll 03.12.2018 10:33

Еще один скомпилированный SFINAE, который можно сделать очень тривиальным с помощью C++ 17 if constexpr.

DeiDei 03.12.2018 10:40
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
90
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Проблема в том, что аргументы шаблона по умолчанию не являются частью подпись шаблона функции. Два SomeFunction считаются идентичными, что вызывает ошибку повторного объявления.

Two function templates are considered equivalent if

  • they are declared in the same scope
  • they have the same name
  • they have identical template parameter lists
  • the expressions involving template parameters in their return types and parameter lists are equivalent

Вы можете использовать их в возвращаемых типах, например (для C++ 11)

template <typename T_ = T>
typename std::enable_if<!std::is_pointer<T_>::value>::type SomeFunction()
{
    // Do nothing
}
template <typename T_ = T>
typename std::enable_if<std::is_pointer<T_>::value>::type SomeFunction()
{
    // Do sth
}

РЕАЛЬНЫЙ

Или используйте их в списке параметров шаблона без типа, например (для C++ 11)

template < typename T_ = T, typename std::enable_if<!std::is_pointer<T_>::value>::type* = nullptr>
void SomeFunction()
{
    // Do nothing
    std::cout << "Do nothing\n";
}
template < typename T_ = T, typename std::enable_if<std::is_pointer<T_>::value>::type* = nullptr>
void SomeFunction()
{
    // Do sth
    std::cout << "Do sth\n";
}

РЕАЛЬНЫЙ

Отлично! Немного более чистая версия была бы template < typename T_ = T, typename std::enable_if_t < !std::is_pointer<T_>{} >* = nullptr>

razvanimal 03.12.2018 11:53

Проблема в том, что два объявления шаблона функции - это эквивалент, поэтому компилятор считает, что ваш код содержит 2 определения функций для уникальной функции.

Эквивалентность шаблонов функций описана в [temp.over.link] / 6 и [temp.over.link] / 7.

В вашем конкретном случае проблема в том, что этот эквивалентность не принимает во внимание аргумент шаблона по умолчанию.

Если вы добавите параметр шаблона по умолчанию, эти две функции не будут эквивалентны:

   template < typename T_ = T
            , typename = std::enable_if_t <!std::is_pointer<T_>{} > >
    void SomeFunction()
    {
        // Do nothing
    }
    template < typename T_ = T
             , class=void
             , typename = std::enable_if_t < std::is_pointer<T_>{} > >
    void SomeFunction()
    {
        // Do sth
    }

Другие вопросы по теме