Устранить повторение в коде C++?

Учитывая следующее:

StreamLogger& operator<<(const char* s) {
  elements.push_back(String(s));
  return *this;
}

StreamLogger& operator<<(int val) {
  elements.push_back(String(asString<int>(val)));
  return *this;
}

StreamLogger& operator<<(unsigned val) {
  elements.push_back(String(asString<unsigned>(val)));
  return *this;
}

StreamLogger& operator<<(size_t val) {
  elements.push_back(String(asString<size_t>(val)));
  return *this;
}

существует ли способ устранить повторение? Я хочу использовать шаблоны, но я только хочу это для следующих типов: символ константы* интервал, неподписанный, и size_t

6
задан anon 24 February 2010 в 04:52
поделиться

2 ответа

На самом деле, в «ванильном» C ++ вы либо пишете вручную для определенных типов, либо используете шаблон, подобный тому, как он был предложен.

Тем не менее, если вы можете использовать Boost, это сделает то, что вы хотите:

template <class T>
StreamLogger& operator<<(T val)
{
    typedef boost::mpl::vector<const char*, int,
                                unsigned, size_t> allowed_types;

    BOOST_MPL_ASSERT_MSG(boost::mpl::contains<allowed_types, T>::value,
                            TYPE_NOT_ALLOWED, allowed_types);

    // generic implementation follows
    elements.push_back(boost::lexical_cast<std::string>(val));

    return *this;
}

Это вызовет ошибку времени компиляции с сообщением TYPE_NOT_ALLOWED , встроенным в нее, если тип, который компилируется, не содержится в список типов.

Кроме того, поскольку этот ответ требует Boost, я просто использовал lexical_cast . Вы заметите, что повторяете этот код, и это плохо. Рассмотрим обертывание этой функциональности в функцию.


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

template <typename T, typename U>
struct is_same
{
    static const bool value = false;
};

template <typename T>
struct is_same<T, T>
{
    static const bool value = true;
};

template <bool>
struct static_assert;

template <>
struct static_assert<true> {}; // only true is defined

// not the best, but it works
#define STATIC_ASSERT(x) static_assert< (x) > _static_assert_

template <class T>
StreamLogger& operator<<(T val)
{
    STATIC_ASSERT(is_same<const char*, T>::value ||
                    is_same<int, T>::value ||
                    is_same<unsigned, T>::value ||
                    is_same<size_t, T>::value);

    // generic implementation follows
    elements.push_back(boost::lexical_cast<std::string>(val));

    return *this;
}

Это также вызовет ошибку времени компиляции, если утверждение не выполняется, хотя код не так сексуально. :( <- Не сексуально

6
ответ дан 17 December 2019 в 00:08
поделиться

Должно сработать что-то вроде этого:

template <class T>
StreamLogger& operator<<(T val) {
  istringstream s;
  s << val;
  elements.push_back(s.str()); // assuming elements is a vector<string>
  return *this;
}
1
ответ дан 17 December 2019 в 00:08
поделиться
Другие вопросы по тегам:

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