2010-02-24 64 views
6

考虑以下几点:消除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; 
} 

有消除重复的方法吗?我想使用的模板,但我只是想对以下几种类型:为const char *整型,无符号,并为size_t

+0

@anon:你想只为这些类型或它可以接受的其他类型吗?换句话说,如果您尝试使用其他类型应该发生什么?编译器错误或不 - op或push_back()插入向量? – Naveen 2010-02-24 05:13:15

+1

重复:http://stackoverflow.com/questions/148373/c-restrict-template-function – Clifford 2010-02-24 05:32:36

+1

@Clifford:但是没有一个像我的解决方案一样性感。:) – GManNickG 2010-02-24 05:34:05

回答

6

真的,在“香草” C++你无论是用手写,还是用特定的类型,或者使用像Dirkgently建议的模板。

这就是说,如果你可以使用升压这个你想要做什么:

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。您会注意到您正在重复该代码,这很糟糕。考虑将wrapping这个功能变成一个函数。


如果您能使用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; 
} 

这也将产生一个编译时错误,尽管代码不如性感。 :(< - 不性感

+1

不幸的是,编译器错误可能不是性感:) – 2010-02-24 08:31:56

1

像这样的东西应该工作:

template <class T> 
StreamLogger& operator<<(T val) { 
    istringstream s; 
    s << val; 
    elements.push_back(s.str()); // assuming elements is a vector<string> 
    return *this; 
} 
+0

但是OP只希望它用于特定类型。 – Naveen 2010-02-24 05:04:58

+0

@Naveen:不知道他是否想要一个受限制的模板,或者如果这些是他需要的_only_类型。一些澄清将有所帮助。 – dirkgently 2010-02-24 05:06:22

+0

@ *:FWIW,可以使用Boost.Type Traits和'BOOST_STATIC_ASSERT'来检查特定类型。 – dirkgently 2010-02-24 05:22:42