Open agraham-roku opened 1 month ago
@llvm/issue-subscribers-clang-frontend
Author: Aaron Graham (agraham-roku)
It doesn't look like a bug, just the additional diagnostic (not mandated by the standard) which is implemented in Clang, but not implemented in GCC and MSVC (https://godbolt.org/z/s7YrfPPsh).
template <typename Period>
struct duration {};
template <typename Period, typename Period2>
duration(duration<Period>) -> duration<Period2>;
It's true that Period2
cannot be deduced from the such deduction guide signature.
This is a bug - over.match.class.deduct says
For each function or function template f in the guides of the template named by the simple-template-id of the defining-type-id, the template arguments of the return type of f are deduced from the defining-type-id of A according to the process in [temp.deduct.type] with the exception that deduction does not fail if not all template arguments are deduced.
hello,
let me contribute,
independently found the error with this sample code:
#include <type_traits>
class C{
public:
operator int() {return 0;};
};
template<typename T1, class T2 = int>
class C2{
public:
C2(T1 t1, T2 t2){};
};
template<class T>
using TT2 = C2<T>;
TT2 x(1,2); // ok: C2<int,int>
TT2 y(3,'4'); // rejected by clang 19.1.0, but accepted by gcc 14.2 and MVSC 19.latest
TT2 z(5,C()); // rejected by clang 19.1.0, but accepted by gcc 14.2 and MVSC 19.latest
static_assert(std::is_same_v<decltype(x),decltype(y)>); // ok for gcc and MVSC
static_assert(std::is_same_v<decltype(y),decltype(z)>); // ok for gcc and MVSC
y is refused with the following error, and similarly z with C instead of char:
error: no viable constructor or deduction guide for deduction of template arguments of 'TT2'
| TT2 y(3,'4');
| ^
note: candidate template ignored: constraints not satisfied [with T = int, T2 = char]
| using TT2 = C2<T>;
| ^
note: cannot deduce template arguments for 'TT2' from 'C2<int, char>'
note: implicit deduction guide declared as 'template <class T, class T2 = int> requires __is_deducible(TT2, C2<T, T2>) TT2(T t1, T2 t2) -> C2<T, T2>'
note: candidate function template not viable: requires 1 argument, but 2 were provided
| class C2{
| ~~
| public:
| C2(T1 t1, T2 t2){};
| };
|
| template<class T>
| using TT2 = C2<T>;
| ^
note: implicit deduction guide declared as 'template <class T, class T2 = int> requires __is_deducible(TT2, C2<T, T2>) TT2(C2<T, T2>) -> C2<T, T2>'
Here's a case where CTAD for template aliases feature isn't working. Minimal code is copied below, but here also are godbolt links:
template <typename Rep, typename Period> struct duration { constexpr duration(Rep r) : v{r} {}
};
template <typename Rep, typename Period = std::ratio<1>> using seconds = duration<Rep, Period>;
template using milliseconds =
seconds<Rep, std::chrono::milliseconds::period>;
template <typename Rep, typename Period, typename Period2> duration(duration<Rep, Period>) -> duration<Rep, Period2>;
constexpr auto d1 = seconds{1}; constexpr auto d2 = milliseconds{d1}; static_assert(d2.v.count() == 1000);
int main() {}