https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93275
Bug ID: 93275
Summary: Error when calculating template parameters in
recursive template function call
Product: gcc
Version: 9.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: tahasuf at gmail dot com
Target Milestone: ---
Clang and GCC 8 can compile the code without any errors. But GCC 9 gives an
error.
#include <algorithm>
#include <array>
#include <iostream>
namespace math {
/** forward declaration **/
template <typename T, std::size_t N>
struct array;
/** is_array **/
template <typename T>
struct is_array: std::false_type {};
template <typename T, std::size_t N>
struct is_array<array<T, N>>: std::true_type {};
template <typename T>
inline constexpr bool is_array_v = is_array<T>::value;
/** array_depth **/
template <typename T>
struct array_depth: std::integral_constant<std::size_t, 0> {};
template <typename T, std::size_t N>
struct array_depth<array<T, N>>:
std::integral_constant<std::size_t, 1 + array_depth<T>::value>
{};
template <typename T>
inline constexpr bool array_depth_v = array_depth<T>::value;
/** array **/
template <typename T, std::size_t N>
struct array: std::array<T, N> {
constexpr array operator * (const array& other) const {
array result {};
std::transform(
std::begin(*this),
std::end(*this),
std::begin(other),
std::begin(result),
std::multiplies<T>());
return result;
}
template <typename Other, std::enable_if_t<
(array_depth_v<array> > array_depth_v<Other>),
std::nullptr_t> = nullptr>
constexpr array operator * (const Other& other) const {
array result {};
std::transform(
std::begin(*this),
std::end(*this),
std::begin(result),
[other](const T& t) { return t * other; });
return result;
}
friend std::ostream&
operator << (std::ostream& out, const array& source) {
out << "<array" << N;
if constexpr (!is_array_v<T>)
out << typeid(T).name();
for (auto it: source) {
if constexpr (!is_array_v<T>)
out << " ";
out << it;
}
out << ">";
return out;
}
};
}
int main() {
math::array<math::array<float, 4>, 1> a0
{{math::array<float, 4>{{1.f, 2.f, 3.f, 4.f}}}};
std::cout << a0 * 4.f << std::endl;
return 0;
}