François Andrieuxthis Visual Studio 2017 problem提供了一个很好的解决方法。我试图像这样回答他:

template<class T, size_t N>
ostream& vector_insert_impl(ostream& lhs, const char*, const T& rhs)
{
    return lhs << at(rhs, N);
}

template<class T, size_t N, size_t... I>
ostream& vector_insert_impl(ostream& lhs, const char* delim, const T& rhs)
{
    return vector_insert_impl<T, I...>(lhs << at(rhs, N) << delim, delim, rhs);
}

template <typename T, size_t... I>
ostream& vector_insert(ostream& lhs, const char* delim, const T& rhs, index_sequence<I...>)
{
    return vector_insert_impl<T, I...>(it, delim, rhs);
}

关键区别在于,“递归结束”模板函数实际上将最后一个值插入ostream,而不是定界符而不是空操作。但是当我尝试编译它时,我得到了错误:



我认为可变长度模板函数被认为是三等公民,而固定长度模板函数将永远是首选。该首选项在这里似乎无效。有没有变通办法,将迫使编译器选择我的“递归结束”功能,使我避免插入定界符?

最佳答案



您可以添加“Next”元素

template <typename T, std::size_t N>
std::ostream & vector_insert_impl (std::ostream & lhs, char const *, T const & rhs)
{
    return lhs << at(rhs, N);
}

// ..................................vvvvvvvvvvvvvvvv
template <typename T, std::size_t N, std::size_t Next, std::size_t ... I>
std::ostream & vector_insert_impl (std::ostream & lhs, char const * delim, T const & rhs)
{ // ............................vvvv
    return vector_insert_impl<T, Next, I...>(lhs << at(rhs, N) << delim, delim, rhs);
}

但是,如果可以使用C++ 17,我认为if constexpr是更好的解决方案
template <typename T, std::size_t N, std::size_t ... Is>
std::ostream & vector_insert_impl (std::ostream & lhs, char const * delim, T const & rhs)
{
   if constexpr ( sizeof...(Is) )
      return vector_insert_impl<T, Is...>(lhs << at(rhs, N) << delim, delim, rhs);
   else
      return lhs << at(rhs, N);
}

关于c++ - 重载可变长度模板函数的递归结束,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56653029/

10-11 18:37