From 8a7109f9c54185b27f36859fdb379a67899ee4e4 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Tue, 26 Apr 2022 13:26:02 +0200 Subject: [PATCH] Fix compilation due to failing template deduction for aggregates gcc 11.2.0 compiles us just fine but clang 13.0.1 fails with this error clang++ -DKAK_DEBUG -O0 -pedantic -std=c++2a -g -Wall -Wextra -Wno-unused-parameter -Wno-sign-compare -Wno-address -frelaxed-template-template-args -Wno-ambiguous-reversed-operator -MD -MP -MF .ranges.debug.d -c -o .ranges.debug.o ranges.cc ranges.cc:30:17: error: no viable constructor or deduction guide for deduction of template arguments of 'Array' check_equal(Array{{""_sv, "abc"_sv, ""_sv, "def"_sv, ""_sv}} | flatten(), "abcdef"_sv); ^ ./constexpr_utils.hh:14:8: note: candidate template ignored: couldn't infer template argument 'T' struct Array ^ ./constexpr_utils.hh:14:8: note: candidate function template not viable: requires 0 arguments, but 1 was provided 1 error generated. The same error can be reproduced with this C++ input template struct Array { T m_data[N]; }; void test() { (void)Array{{1, 2}}; } Since "Array" has no constructor, the compiler uses aggregate initialization. Only recent g++ seems to be smart enough to deduce template arguments in this case. Help other compilers by adding a deduction guide. The deduction guide needs to count the array elements to infer the array size, hence we need to remove braces. Happily, this is allowed and it's also what std::array does. Closes #4597 --- src/constexpr_utils.hh | 3 +++ src/ranges.cc | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/constexpr_utils.hh b/src/constexpr_utils.hh index d9ba2abb..f83faacb 100644 --- a/src/constexpr_utils.hh +++ b/src/constexpr_utils.hh @@ -28,6 +28,9 @@ struct Array T m_data[N]; }; +template requires (std::is_same_v and ...) +Array(T, U...) -> Array; + template constexpr Array make_array(const T (&data)[N], std::index_sequence) { diff --git a/src/ranges.cc b/src/ranges.cc index 4fe2a418..b8fb6703 100644 --- a/src/ranges.cc +++ b/src/ranges.cc @@ -27,7 +27,7 @@ UnitTest test_ranges{[] { check_equal(R"(\\,\\,)"_sv | split(',', '\\') | transform(unescape<',', '\\'>), Strs{R"(\)", R"(\)", ""}); - check_equal(Array{{""_sv, "abc"_sv, ""_sv, "def"_sv, ""_sv}} | flatten(), "abcdef"_sv); + check_equal(Array{""_sv, "abc"_sv, ""_sv, "def"_sv, ""_sv} | flatten(), "abcdef"_sv); check_equal(Vector{"", ""} | flatten(), ""_sv); check_equal(Vector{} | flatten(), ""_sv); }};