поведение шаблона, основанное на существовании функции

У меня есть шаблон класса foo

template <typename Item>
class foo
{
void method()
{
// ...
}
}

что мне нужно, это изменить реализацию метода, основанного на типе элемента, на основе, если функция скажет unsigned int hasher(const Item& item) существует.

Мой вопрос — как это технически возможно, и если нет, то как я мог бы организовать код, чтобы иметь это?

Обратите внимание, что для алгоритма важна производительность, и я ищу решения, которые позволят компиляторам решать разницу времени компиляции.

1

Решение

Вам необходимо применить шаблон политики, взгляните на:
http://en.wikipedia.org/wiki/Policy-based_design
также
Шаблоны C ++

1

Другие решения

В течение многих лет не касался кода на C ++, поэтому не могу написать вам пример на месте [ну, может, я смогу, но результаты были бы веселыми], но, как указано в этот ответ силы, которые вы ищете, можно найти в SFINAE

0

// Macro helper to create traits
#define HAS_TEMPLATED_FUNC(traitsName, funcName, Prototype)                          \
namespace detail {                                                               \
template<typename U>                                                             \
class traitsName                                                                 \
{                                                                                \
typedef std::uint8_t yes;                                                    \
typedef std::uint16_t no;                                                    \
template <typename T, T> struct type_check;                                  \
template <typename T = U> static yes &chk(type_check<Prototype, &funcName>*); \
template <typename > static no &chk(...);                                    \
public:                                                                          \
static bool const value = sizeof(chk<U>(0)) == sizeof(yes);                  \
};                                                                               \
}                                                                                \
template <typename U>                                                            \
struct traitsName : std::conditional<detail::traitsName<U>::value,               \
std::true_type, std::false_type>::type {}

Теперь предположим, что:

unsigned int hasher(const int& item);

Теперь создайте черту:

HAS_TEMPLATED_FUNC(has_hasher, hasher, unsigned int (*)(const T&));

// some test.
static_assert(has_hasher<int>::value, "");
static_assert(!has_hasher<char>::value, "");

Теперь есть какой-то способ использовать его

Диспетчерская метка:

template <typename Item>
class foo
{
public:
void method()
{
method(has_hasher<Item>());
}
private:
void method(std::true_type)
{
// You may use hasher here.
hasher(Item{});
}
void method(std::false_type)
{
// You cannot use hasher here.
}
};

или сфина:

template <typename Item>
class foo
{
public:
template <typename T = Item>
typename std::enable_if<has_hasher<T>::value, void>::type
method()
{
// You may use hasher here.
hasher(Item{});
}

template <typename T = Item>
typename std::enable_if<!has_hasher<T>::value, void>::type
method()
{
// You cannot use hasher here.
}
};
0
По вопросам рекламы [email protected]