Template argument deduction for parenthesized initialization of aggregates in C++
Asked Answered
P

2

8

In the following code there is an initialization of A<T> objects with template argument deduction using two forms distinct by the type of braces:

template<typename T>
struct A{ T x; };

int main() {
    static_assert( A{1}.x == 1 ); //#1: ok in GCC and MSVC
    static_assert( A(1).x == 1 ); //#2: ok in GCC only
}

The first way is accepted by both GCC and MSVC, while the second one is ok for GCC only while MSVC prints errors:

error C2641: cannot deduce template arguments for 'A'
error C2780: 'A<T> A(void)': expects 0 arguments - 1 provided
error C2784: 'A<T> A(A<T>)': could not deduce template argument for 'A<T>' from 'int'

Demo: https://gcc.godbolt.org/z/97G1acqPr

Is it a bug in MSVC?

Particle answered 14/11, 2021 at 8:34 Comment(1)
Not 100% sure, but it seems like MSVC is in the wrong here. Both work, if you add a constructor though: constexpr A(T v= T{}) : x(v){}Devol
M
6

This is a bug in MSVC.

The following papers were all introduced in C++20:

Whilst MSVC lists them all as implemented in their Microsoft C/C++ language conformance by Visual Studio version pages, it seems whilst they have correctly implemented them in isolation

// OK (P0960R3, P1975R0)
struct A { int x; };
A a(1);

// OK (P2131R0)
template<typename T>
struct B { T x; };
B b{1};

// rejects-invalid (allowed by the union of the papers)
template<typename T>
struct C { T x; };
C c(1);

MSVC seems to have missed implementing the union of the papers. I have not, however, been able to find an open bug report.

Maria answered 15/11, 2021 at 13:34 Comment(1)
Thanks, I submitted MSVC bug: developercommunity.visualstudio.com/t/…Particle
S
3

These lines being well-formed relies on an aggregate deduction candidate, which provides a way for T to be deduced from aggregate intialization lists. This feature is indifferent to the syntax, so failing on either one but not the other is already inconsistent.

In MSVC's case, it's the combination of class template parameter deduction and parenthesized aggregate intialization that is causing the issue (the latter works fine in isolation). MSVC also fails to compile A a(1);, which is more obviously well-formed.

Sherleysherline answered 15/11, 2021 at 12:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.