I have this class
template <typename ValueType, std::size_t Size>
struct ArrayPrimitive
{
constexpr ArrayPrimitive(const ValueType (&array)[Size]) {
std::copy(array, array + Size, data_);
}
ValueType data_[Size];
};
which is my attempt on generalizing the wrapper for passing string literals as NTTP. Then I declare this variable template, making use of CTAD
template <ArrayPrimitive array>
std::integral_constant<decltype(array), array> arr;
and afterwards use it in code as such
for (auto i : arr<{{2,4,6}}>.value.data_) std::cout << i << std::endl;
It compiles and properly prints all the values.
The compiler I used was the gcc13.2, I know it won't work on clang as of now due to c++20's support for class NTTP not being there yet. Also VS Code's code analyzer really doesn't like the brackets in template instantiation, which is a bit weird because it doesn't have problem with arr<"123">
.
I want to know if it's standard compliant and won't break with future changes.
EDIT: Looking at the answer for the bug report GCC bug 111277, it seems GCC has indeed implemented CWG 2450, placing it in realms of intended behaviour, however only for this one compiler.
EDIT2: It seems it also compiles with MSVC if I write it like this https://gcc.godbolt.org/z/1sThrse3x
std::array
e.g.ArrayPrimitive(const std::array<ValueType, Size> array)
and use it likearr<std::array{2,4,6}>
, which works on all compilers. – Stocktonontees<{...}>
is legal, GCC and MSVC reject it. If you go for<std::array{...}>
, all three compilers accept it: gcc.godbolt.org/z/EYnxKaThh – Export