Приоритет при выборе перегруженного шаблона функционирует в C++

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

16
задан mmmmmmmm 26 August 2009 в 08:11
поделиться

5 ответов

Я нашел ОЧЕНЬ простое решение!

class Base
{
};

class Derived : public Base
{
};

class Different
{
};

class X
{
private:
  template <typename T>
  static const char *intFunc(const void *, T *data)
  {
    // Do something generic...
    return "Generic";
  }

  template <typename T>
  static const char *intFunc(const Base *, T *data)
  {
    // Do something specific...
    return "Specific";
  }

public:
  template <typename T>
  static const char *func(T *data)
  {
    return intFunc(data, data);
  }
};

Он отлично работает и очень тонкий! Уловка состоит в том, чтобы позволить компилятору выбрать правильный метод с помощью (в противном случае бесполезного) первого параметра.

16
ответ дан 30 November 2019 в 21:29
поделиться

Для этого необходимо использовать SFINAE . В следующем коде первая функция может быть создана тогда и только тогда, когда вы передаете что-то, что не может быть (неявно) преобразовано в Base * . Вторая функция имеет обратное.

Вы можете прочитать enable_if .

#include <iostream>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits.hpp>

class Base {};
class Derived : public Base {};
class Different {};

struct X
{
    template <typename T>
    static typename boost::disable_if<boost::is_convertible<T *, Base *>,
        const char *>::type func(T *data)
    {
        return "Generic";
    }

    template <typename T>
    static typename boost::enable_if<boost::is_convertible<T *, Base *>,
        const char *>::type func(T *data)
    {
        return "Specific";
    }
};

int main()
{
    Derived derived;
    Different different;
    std::cout << "Derived: " << X::func(&derived) << std::endl;
    std::cout << "Different: " << X::func(&different) << std::endl;
}
8
ответ дан 30 November 2019 в 21:29
поделиться

Если вы используете ускорение, вы можете сделать это с помощью некоторого метапрограммирования шаблона:

#include <boost/type_traits/is_base_of.hpp>

class X
{
private:
    template <typename T>
    static const char *generic_func(T *data)
    {
        // Do something generic...
        return "Generic";
    }

    template <typename T>
    static const char *base_func(T *data)
    {
        // Do something specific...
        return "Specific";
    }

public:
    template <typename T>
    static const char* func(T* data)
    {
        if (boost::is_base_of<Base, T>::value)
            return base_func(data);

        return generic_func(data);
    }
};

Метафункция is_base_of оценивается во время компиляции, и оптимизатор, скорее всего, удалит мертвая ветвь if в функции func . Такой подход позволяет иметь более одного конкретного случая.

1
ответ дан 30 November 2019 в 21:29
поделиться

Выражение:

X::func(derived)

Означает, что компилятор сгенерирует объявление и код, который фактически имеет эту сигнатуру:

static const char *func(Derived *data);

, которая оказывается более подходящей, чем ваша:

static const char *func(Base *data);

Функция шаблона будет использоваться для всего, что допустимо для typename, например, для любого класса, который вы используете как T, и он будет эффективно исключать использование Base версии вашей функции из-за политики времени компиляции.

Я предлагаю использовать специализация в X для ваших конкретных типов, например:

template <typename T>
  static const char *func(T *data)
  {
    // Do something generic...
    return "Generic";
  }

template <>
  static const char *func(Derived *data) // 'Derived' is the specific type
  {
    // Do something specific...
    return "Specific";
  }

Надеюсь, что это сработает!

1
ответ дан 30 November 2019 в 21:29
поделиться

Просто приведение типов, производное от base

X :: func ((Base *) & производное)

работает ....

0
ответ дан 30 November 2019 в 21:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: