Obwohl es C++ 17-fache Ausdrücke beinhaltet, die eine möglichst einfache Lösung durch den Kommentar von Jarod42 inspiriert ist:
#include <array>
template <typename T, size_t N>
struct A
{
template <typename ... Ts>
A(Ts ... vals)
{
size_t i = 1; // starting index, can be an argument
((arr[i++] = vals) , ...);
}
std::array<T, N> arr;
};
int main()
{
A<int, 4> a(1, 2, 3);
return 0;
}
diese Kompilieren mit Clang 3.6 oder oben mit Optimierungsstufe -O1
und -std=c++1z
Flagge der erzeugt Montage ist:
A<int, 4ul>::A<int, int, int>(int, int, int): # @A<int, 4ul>::A<int, int, int>(int, int, int)
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movl %ecx, %r14d
movl %edx, %r15d
movl %esi, %ebx
movq %rdi, %rbp
movl $1, %esi
callq std::array<int, 4ul>::operator[](unsigned long)
movl %ebx, (%rax)
movl $2, %esi
movq %rbp, %rdi
callq std::array<int, 4ul>::operator[](unsigned long)
movl %r15d, (%rax)
movl $3, %esi
movq %rbp, %rdi
callq std::array<int, 4ul>::operator[](unsigned long)
movl %r14d, (%rax)
addq $8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
, die zu den Testfall entspricht
template <typename T, size_t N>
struct B
{
B(T x, T y, T z)
{
arr[1] = x;
arr[2] = y;
arr[3] = z;
}
std::array<T, N> arr;
};
int main()
{
B<int, 4> b(1, 2, 3);
return 0;
}
mit generierte Assembly
B<int, 4ul>::B(int, int, int): # @B<int, 4ul>::B(int, int, int)
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movl %ecx, %r14d
movl %edx, %r15d
movl %esi, %ebx
movq %rdi, %rbp
movl $1, %esi
callq std::array<int, 4ul>::operator[](unsigned long)
movl %ebx, (%rax)
movl $2, %esi
movq %rbp, %rdi
callq std::array<int, 4ul>::operator[](unsigned long)
movl %r15d, (%rax)
movl $3, %esi
movq %rbp, %rdi
callq std::array<int, 4ul>::operator[](unsigned long)
movl %r14d, (%rax)
addq $8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
Es lohnt sich zu beachten, dass die erzeugte Anordnung der beiden Fall entspricht.
@Yakk: Der ganze Sinn von C++ in diesen Tagen ist die Leistung. Temporäre Container zu erstellen steht dem im Gegensatz. Es nimmt unnötigen Platz ein und verursacht den Aufruf von unnötigen Konstruktoren, wobei möglicherweise viele Ressourcen abhängig davon zugewiesen werden, was "T" ist. Ich sehe keine Notwendigkeit, warum er rechtfertigen sollte, warum er das Parameterpack nicht in irgendeine Art von Objekt konvertieren will. –
Es scheint mir Montagmorgen ist etwas schwer für Leute nach Ostern. Die Frage ist klar, aber ich sehe zwei respektvolle Mitglieder von SO, die OP mit irrelevanten Aussagen anstürmen, anstatt die Frage zu beantworten. – SergeyA
@NicolBolas Das sind alles gute Gründe. Aber eine 'std :: tie' ist ein Container von Referenzen, deren Existenz und Größe (theoretisch) entzogen werden kann. Und es ist ein Tupel. – Yakk