I am puzzled about this C code:
template <class T>
struct Foo {
T value;
};
int main() {
return Foo<int>(0).value;
// Below code works as well in gcc
// return Foo(0).value;
}
It compiles with GCC 10 in C 20 standard (but not in C 17 standard) and latest MSVC, but not with clang 13 or 14, even in C 20.
According to the standard (from cppreference) it should be possible to instantiate Foo
at least when specifying the templated type.
Why is this related to C 20 ? I see nothing that change in the template deduction specification (I maybe missed something).
Also (this is strange), GCC in C 20 mode even compiles when we call Foo
without specifying templated type (Foo(0)
).
godbolt link here
CodePudding user response:
It compiles with GCC 10 in C 20 standard (but not in C 17 standard) and latest MSVC.
This is because GCC 10 and the latest MSVC implement allow initializing aggregates from a parenthesized list of values, which allows us to use parentheses to initialize aggregates.
Also (this is strange), GCC in C 20 mode even compiles when we call Foo without specifying templated type (
Foo(0)
).
This is because GCC 10 implements class template argument deduction for aggregates, which makes T
automatically deduced to int
.
Please note that clang does not currently implement these two C 20 features, so your code cannot be accepted by clang.
You can refer to cppreference to get the current compiler's support for C 20 features.
CodePudding user response:
Regarding your link, the compiler will tell you what's wrong with your call:
error: no matching function for call to 'Foo::Foo(int)'
So, the problem is that you try to call a non-existing constructor. Your class Foo
has the default constructor Foo()
only.
Just change return Foo<int>(0).value;
to return Foo<int>().value;
and it would work. Otherwise you would need a constructor like Foo(T) {}
.