Условное поведение функции на основе указателя типа шаблона - PullRequest
0 голосов
/ 03 декабря 2018

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

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

Не уверен, относится ли к этому 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: функция-член уже определена или объявлена ​​.

Ответы [ 2 ]

0 голосов
/ 03 декабря 2018

Проблема в том, что объявление шаблона двух функций эквивалентно , поэтому компилятор считает, что ваш код содержит 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
    }
0 голосов
/ 03 декабря 2018

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

Два функциональных шаблона считаются эквивалентными, если

  • они объявлены в одной и той же области действия
  • они имеют одинаковые имена
  • они имеют идентичные списки параметров шаблона
  • выражения, включающие параметры шаблона в их возвращаемых типах и списках параметров, эквивалентны

Вы можете использовать их в возвращаемых типах, например (для 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
}

LIVE

Или использовать их в нетиповом параметре шаблонасписок, например (для 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";
}

LIVE

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