Мой взгляд на это: вы можете взять метафункцию, которую вы нашли, как есть, она прекрасно работает. Давайте все же кратко обсудим, почему это работает:
sizeof
на самом деле не вычисляет выражение; он выводит свой тип и возвращает размер этого типа. Размеры типов определяются реализацией, и мы не можем ничего о них предположить, но мы знаем, что это sizeof(char) != sizeof(char[2])
, поэтому мы используем эти типы для тестирования.
Мы определяем оператор потока на уровне пространства имен, используя тип any_t
, который примет — как вы уже догадались — любой тип и позволит ему что-то вернуть (на самом деле не важно, какой тип, если это не ostream &
). Это то, к чему мы возвращаемся, если для типа не определен оператор потока. В самом классе мы теперь определяем две функции, одна принимает ostream &
, который будет результатом, если оператор потока определен, а другая принимает возвращаемый тип, который мы определили для нашей резервной функции.
Теперь мы можем протестировать sizeof(test(s << c))
, который, опять же, не будет вычислять выражение, а только определит тип возвращаемого значения и вернет его размер.
Теперь все, что мы поняли, как это работает, осталось только встроить это в наше приложение. Для этого есть несколько подходов; один из способов, который также работает до С++ 11, заключается в использовании функтора:
template <bool, typename T>
struct to_string_functor
{
std::string operator()(T const & t) const
{
std::stringstream ss;
ss << t;
return ss.str();
}
};
template <typename T>
struct to_string_functor<false, T>
{
std::string operator()(T const &) const
{
return typeid(T).name();
}
};
template <typename T>
struct foo
{
std::string to_string() const
{
return to_string_functor<
has_insertion_operator<T>::value, T
>()(m_Value);
}
/* ... */
};
Есть и другие способы сделать это, еще один — enable_if
, если вам доступен C++11 (вам, вероятно, понадобятся частично специализированные функции для этого); вы можете прочитать эту замечательную запись в блоге об этом иметь значение.
Однако в этом простом случае, на мой взгляд, должен подойти функтор.
person
nijansen
schedule
04.09.2013