// std::array needs double {{..}} to initialize objects
19
actorDigital{{Actor("DigitalOut1"),
20
Actor("DigitalOut2"),
21
Actor("DigitalOut3"),
22
Actor("DigitalOut4"),
23
Actor("DigitalOut5"),
24
Actor("DigitalOut6"),
25
Actor("DigitalOut7"),
26
Actor("DigitalOut8"),
27
Actor("DigitalOut9"),
28
Actor("DigitalOut10"),
29
Actor("DigitalOut11"),
30
Actor("DigitalOut12"),
31
Actor("DigitalOut13"),
32
Actor("DigitalOut14"),
33
Actor("DigitalOut15"),
34
Actor("DigitalOut16")
35
}}
36
{
37
}
Zuerst hatte ich noch keine baseAddress im Actor() und habe von Hand die
Namen vergeben, was mir eigentlich schon nicht gefiel. Nun müsste ich
noch anhand des Index die baseAddress vergeben, dies wäre etwas in der
Art:
address + (index * x)
Genauso könnte ich den Namen generieren lassen, ohne von Hand
durchzuzählen, mein Ziel wäre:
Actor("DigitalOut" + to_string(index), address + (index * x) )
Gibt es einen Weg das std::array so zu initialisieren?
Kannst du mir mehr über die statischen Datenmember sagen? (Link zu
beispiel oder so)
Würde ich stattdessen das array mit pointer füllen, hätte ich vermutlich
so etwas gemacht:
Bei dieser Lösung könnte ich aber gleich zum vector<> gehen und hätte
das ganze sauberer gelöst.
(Das es hier im Beispiel bei 0 Anfangen würde und nicht bei 1 soll mal
ausser acht gelassen werden, aber ich denke die Idee ist klar.)
Am einfachsten in solchen Fällen ist es doch, das einfach mal
auszuprobieren (und schön wäre es, wenn dann im Ausgangsbeitrag schon
compilierbarerer Code gepostet wird):
Oliver S. schrieb:> Am einfachsten in solchen Fällen ist es doch, das einfach mal> auszuprobieren:
Das ist aber undefiniertes Verhalten , pures Glück dass es funktioniert.
Wenn man eine Variable (hier Index) innerhalb eines Ausdrucks mehrfach
verändert passiert etwas Compiler spezifisches...
Operator S. schrieb:> Bei dieser Lösung könnte ich aber gleich zum vector<> gehen und hätte> das ganze sauberer gelöst.
Ja, warum nicht? Dann vllt auf die heap-allocation verzichten?
Die Frage ist: hast Du Allocator auf Deiner Plattform? Schaut aber so
aus, als ob Du nicht auf BareMetal bist ...
Danke für Antworten, es scheint also keine direkte Lösung über
std::array zu geben?
Beitrag "Re: std::array of objects in initializer list"
An dieser Lösung fehlt mir der boundary check, der ja mit array möglich
wäre. Ebenso muss wieder viel geschrieben werden, wollte das eigentlich
vermeiden und nur eine "vorlage" schreiben, die der Compiler richtig
generiert.
Beitrag "Re: std::array of objects in initializer list"
Dieser Ansatz habe ich auch schon angedacht, aber wenn ich ein zweites
array ala
std::array<Actor, 3> actorsDigital;
std::array<Actor, 3> actorsAnalog;
habe, funktioniert es wieder nicht. Der index müsste auf das array
bezogen sein und nicht auf die Objekte.
std::array wollte ich einsetzen da ich eine feste Grösse habe, aber
nicht auf Actor actor[16] setzen wollte, alleine schon wegen
range-based-loops. Irgendwie bin ich aber nie zufrieden mit dem
std::array, so dass ich doch raw-arrays oder std::vector einsetze -
schade.
Bezüglich dem compilierbaren code: Wie so oft ist die eigentliche Klasse
viel grösser und einige Namen mussten firmenbezogen obfuscated werden.
Werde mir aber in Zukunft mehr mühe geben.
Operator S. schrieb:> Actor("DigitalOut" + to_string(index), address + (index * x) )>> Gibt es einen Weg das std::array so zu initialisieren?
Fast! ;-) Es wäre "nur" ein Array und die Lösung ist etwas unleserlich:
1
#include <tuple>
2
#include <type_traits>
3
#include <iostream>
4
#include <array>
5
6
class actor
7
{
8
public:
9
explicit actor( int i ) : id_( "DigitalOut" + std::to_string( i ) ) {}
10
11
std::string id() const
12
{
13
return id_;
14
}
15
16
private:
17
const std::string id_;
18
};
19
20
template < typename T >
21
struct generate_actor;
22
23
template < int I >
24
struct generate_actor< std::integral_constant< int, I > >
25
{
26
static const actor a;
27
};
28
29
template < int I >
30
const actor generate_actor< std::integral_constant< int, I > >::a = actor( I );
Dr. Sommer schrieb:> Das ist aber undefiniertes Verhalten , pures Glück dass es funktioniert.> Wenn man eine Variable (hier Index) innerhalb eines Ausdrucks mehrfach> verändert passiert etwas Compiler spezifisches...
Hm. Ich erkenne deine Kompetenz normalerweise neidlos an, aber...
... hätte da gerne etwas mehr Info.
Der Standard (C++11, Draft N3376) schreibt:
1
Within the initializer-list of a braced-init-list, the initializer-clauses,
2
including any that result from pack expansions (14.5.3), are evaluated in the order in which they appear. That is, every value computation and
3
side effect associated with a given initializer-clause
4
is sequenced before every value computation and side effect associated with any initializer-clause that follows it in the comma-separated list of the
Operator S. schrieb:> Kann man die Position eines Objektes, welches in einem std::array liegt> seinem eigenen Konstruktor übergeben?
Ich hatte mir mal ein make_array geschrieben, um std::array für
bestimmte Fälle "dynamisch" initialisierbar zu machen (nicht exception
safe). Dann könnte man in deinem Fall bspw. über einen std::vector gehen
und folgerndermaßen verfahren:
Danke für all die Lösungen. Ich hatte gehofft irgendwie std::fill oder
std::generate einsetzen zu können, um näher am standard zu bleiben und
weniger eigenen Code zu produzieren, aber das scheint in diesem Fall
nicht möglich zu sein.
Auch sonst im Netz scheints immer auf template magic hinauszulaufen :)