消除C++代码中的重复?

ano*_*non 6 c++ templates dry

鉴于以下内容:

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;
}
Run Code Online (Sandbox Code Playgroud)

有没有办法消除重复?我想使用模板,但我只想要它用于以下类型:const char*int,unsigned和size_t

GMa*_*ckG 6

实际上,在"vanilla"C++中,您可以手动编写特定类型,也可以使用dirkgently建议的模板.

也就是说,如果你可以使用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;
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

如果断言失败,这也会产生编译时错误,尽管代码不那么性感.:( < - 不性感