2012-12-14 53 views
5

目前,我有一个函数模板,像这样的一个vector转换成string(只是一个自然的字符串,使用逗号分隔的元素):执行此模板的更好方法?

//the type T must be passable into std::to_string 
template<typename T> 
std::string vec_to_str(const std::vector<T> &vec); 

正如你所看到的,这只是针对向量其元素可以被传递到内置std::to_string功能(如intdouble等)

是它认为是一个很好的做法有意见,允许T记录?如果不是,我该怎么办?是否有可能以更好的方式执行此操作?

+0

当然,你甚至可以选择使用注释记录,并用SFINAE技术执行。 – aschepler

回答

2

由于std::to_string是C++ 11的功能,我想你可以开放一个C++ 11的解决方案。在这种特殊情况下,你可以在一个SFINAE方式使用后返回类型:

template <typename T> 
auto vec_to_str(const std::vector<T>& vec) -> decltype(std::to_string(std::declval<T>())); 

这将无法替代(和消除过载)如果值类型不适合to_string工作。但是,这并不一定是记录和执行规则最令人愉快的方式。上面的Sfinae技巧可能有一个pre-C++ 11版本,但它不会更漂亮。

一般来说,我会说只要将它记录在注释中(可能带有一个doxygen标记,如\tparam)就可以了)。您可以使用概念检查机制,按照Boost.Concept的风格 - 检查是否需要。

作为一个侧面说明,在这种特定情况下,我可能会建议你依靠std::ostreamoperator <<代替to_string功能,因为它更可能是自定义的类型(例如,一个2D矢量或东西)将配备过载输出到流。

0

直到concepts抵达,您可以使用decltype与匿名类型参数:

template<typename T, 
    typename = decltype(std::to_string(std::declval<T>()))> 
std::string vec_to_str(const std::vector<T> &vec); 
4

随着static_assert和一些表达SFINAE,你可以有一个很好的编译时错误消息:

template<typename T> 
constexpr auto allowed(int) -> decltype(std::to_string(std::declval<T>()), bool()) 
{ 
    return true; 
} 

template<typename> 
constexpr bool allowed(...) 
{ 
    return false; 
} 

template<typename T> 
std::string vec_to_str(const std::vector<T>& vec) 
{ 
    static_assert(allowed<T>(0), "Invalid value type."); 
    return ""; 
} 

struct foo {}; 

int main() 
{ 
    std::vector<int> v_int; 
    vec_to_str(v_int); 

    std::vector<foo> v_double; 
    vec_to_str(v_double);  // static_assert fires here 
} 
相关问题