[BUG] Can't pass dependent type template argument
Title: Can't pass dependent type template argument.
Minimal reproducer (https://cpp2.godbolt.org/z/W1dKeeKso):
f: <T> () std::vector<T::value_type>();
main: () = { }
Commands:
cppfront main.cpp2
clang++18 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -Werror=unused-result -I . main.cpp
Expected result: std::vector<typename T::value_type>.
Actual result and error: std::vector<T::value_type>.
Cpp2 lowered to Cpp1:
//=== Cpp2 type declarations ====================================================
#include "cpp2util.h"
//=== Cpp2 type definitions and function declarations ===========================
template<typename T> [[nodiscard]] auto f() -> auto;
auto main() -> int;
//=== Cpp2 function definitions =================================================
template<typename T> [[nodiscard]] auto f() -> auto { return std::vector<T::value_type>(); }
auto main() -> int{}
Output:
build/main.cpp:18:74: error: template argument for template type parameter must be a type; did you forget 'typename'?
18 | template<typename T> [[nodiscard]] auto f() -> auto { return std::vector<T::value_type>(); }
| ^
| typename
/opt/compiler-explorer/clang-trunk-20231004/bin/../include/c++/v1/__iterator/wrap_iter.h:102:21: note: template parameter is declared here
102 | template <class _Tp, class _Alloc> friend class _LIBCPP_TEMPLATE_VIS vector;
| ^
1 error generated.
See also:
- This formalizes https://github.com/hsutter/cppfront/discussions/628#discussioncomment-6867808 as a bug report for visibility.
It also seems that it is not possible to declare it in any working way current:
typename does not work: (https://cpp2.godbolt.org/z/x4oYsj1E5)
f: <T> () std::vector<typename T::value_type>();
main: () = { }
neither type:
f: <T> () std::vector<type T::value_type>();
main: () = { }
I'm always going back and forth between these issues. I knew something was missing here. It's Herb's intended resolution.
Would you be solving the ambiguity in template-argument the same as with is-as-expression?
Ack: You beat me to it -- I've been out of computer range but was going to reply saying I expected it would be the same as
x is typeandx is (value). The parens aren't needed for things like literals, of course.-- https://github.com/hsutter/cppfront/discussions/628#discussioncomment-6867808
In fact, this issue is linked there, but discussions don't leave tracks on issues.
With the fix above,
we can potentially allow T& and T&& in Cpp2 type-only contexts
to have the same meaning as in Cpp1.
It would allow me to go from
compound_addition_with: <T, U> concept = // clang-format off
addition_with<T, U> &&
requires(inout l: T, d: U) {
- { l += d } is std::same_as<decltype(l)>;
+ { l += d } is std::same_as<cpp1_ref<T>>;
to
compound_addition_with: <T, U> concept = // clang-format off
addition_with<T, U> &&
requires(inout l: T, d: U) {
- { l += d } is std::same_as<cpp1_ref<T>>;
+ { l += d } is std::same_as<T&>;