François Andrieux gave me a good workaround for this Visual Studio 2017 problem. I was trying to build on his answer like so:
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);
}
The key difference is that the "end of recursion" templated function actually inserts the last value into the ostream
, and not the delimiter rather than being a no-op. But when I try to compile this I get the error:
error C2668:
vector_insert_impl
: ambiguous call to overloaded function (compiling source file ....\src\STETestbed\Test.cpp)
note: could bestd::ostream &vector_insert_impl<T,2,>(std::ostream &,const char *,const T &)
note: orstd::ostream &vector_insert_impl<T,2>(std::ostream &,const char *,const T &)
I thought variable length template functions were considered 3rd class citizens and fixed length template functions would always be preferred. That preference doesn't appear to be in effect here. Is there a workaround which will force the compiler to choose my "end of recursion" function enabling me to avoid inserting the delimiter?