I'm using libcxx 16.0.0 from the LLVM project.
In __algorithm/fill_n.h
, there is the following function:
// fill_n isn't specialized for std::memset, because the compiler already optimizes the loop to a call to std::memset.
template <class _OutputIterator, class _Size, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
_OutputIterator
__fill_n(_OutputIterator __first, _Size __n, const _Tp& __value)
{
for (; __n > 0; ++__first, (void) --__n)
*__first = __value;
return __first;
}
The problem is that in my case the function is not optimized to std::memset
. So I would like to do this specialization manually.
I was hoping to add an overload of __fil_n
for trivially copyable _Tp
and contiguous iterators (including std::array's iterator).
So, given the following code,
template <typename T, int N> struct foo_t {
struct iterator {};
};
template <typename T> int f(T) { return 1; }
template <typename T, int N> int f(typename foo_t<T, N>::iterator) { return 2; }
int main() {
foo_t<int, 10>::iterator a;
return f(a);
}
How can I change the signatures of f
so that the second overload is selected at the f
function call in main ?
A solution with a C++ version >= 11 but <20 would be ideal.
with typename foo_t<T, N>::iterator
, T
and N
are non deducible.
friend
function helps:
template <typename T, int N>
struct foo_t {
struct iterator {
friend int f(iterator) { return 2; } // f is no longer template
};
};
template <typename T> int f(T) { return 1; }