微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – enable_if和多个条件的问题

我试图实现一个将泛型类型转换为字符串的函数.积分类型需要使用std :: to_string(),字符串和字符使用std :: string()和逐个元素的元素转换为使用其他方法之一的字符串(取决于它们的内容).

这就是我所拥有的:

//Arithmetic types    

template<class T>
typename std::enable_if<std::is_arithmetic<T>::value,std::string>::type convertToString(const T& t){
    return std::to_string(t);
}

//Other types using string ctor

template<class T>
typename std::enable_if<std::__and_<std::__not_<std::is_arithmetic<T>>::type,std::__not_<std::is_same<T,<T,std::vector<typename T::value_type,typename T::allocator_type>>::value
       >>>::value,std::string>::type convertToString(const T& t){
    return std::string(t);
}

//Vectors

template<class T>
typename std::enable_if<std::is_same<T,typename T::allocator_type>>::value,std::string>::type convertToString(const T& t){
    std::string str;
    for(std::size_t i = 0; i < t.size(); i++){
        str += convertToString(t[i]);
    }
    return str;
}

问题是第二个函数没有编译.如何设计第二个函数以便它编译(和工作)并且不会产生歧义问题?

解决方法

Oktalist’s回答解释了为什么你的类型特征无法编译.此外,您不应该使用__and_和__not_.这些是保留的,可以在下一个编译器版本中轻松更改.实现这些特征的自己版本很容易(例如,参见 conjunction的可能实现).

我建议采用完全不同的方法.我们可以使用选择<>使这些情况重载更简单:

template <int I> struct choice : choice<I+1> { };
template <> struct choice<10> { };

通过:

// arithmetic version
template <class T>
auto convertToStringHelper(T const& t,choice<0> )
    -> decltype(std::to_string(t))
{
    return std::to_string(t);
}

// non-arithmetic version
template <class T>
auto convertToStringHelper(T const& t,choice<1> )
    -> decltype(std::string(t))
{
    return std::string(t);
}

// vector version
template <class T,class A>
std::string convertToStringHelper(std::vector<T,A> const& v,choice<2> )
{
    // implementation here
}

template <class T>
std::string convertToString(T const& t) {
    return convertToStringHelper(t,choice<0>{});
}

这很好,因为你得到的所有SFINAE都没有任何enable_if cruft.

原文地址:https://www.jb51.cc/c/117249.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐