Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: fortran1986 09. 12. 2020, 01:04:55
-
Na úvod len spomeniem že používam najnovšiu verziu C++ kompilátr čisatočne podporuje C++ 20, ktorá ešte tuším ani neni hotová, ale niektoré časti normy sú už známe a všetky najrzšírenejšie C++ kompilátory ju do určitej miery podporujú... To čo tu rozoberám je súčasťou C++ 20... a teraz k veci.
Mám takýto typ:
struct FileTimesInfo
{
const __time64_t LastAccessTime;
const __time64_t LastModificationTime;
const __time64_t LastStatusChangeTime;
};
ktorý vieme inicializovať takto (namiesto núl si tam doplnte hodnoty aké chcete):
auto ti = FileTimesInfo{ .LastAccessTime = 0, .LastModificationTime = 0, .LastStatusChangeTime = 0 };
keď ale typu pridám nejaký konštruktor napr.
struct FileTimesInfo
{
const __time64_t LastAccessTime;
const __time64_t LastModificationTime;
const __time64_t LastStatusChangeTime;
FileTimesInfo(struct _stati64 stat) :
LastAccessTime(stat.st_atime),
LastModificationTime(stat.st_mtime),
LastStatusChangeTime(stat.st_ctime)
{
}
};
Tak sa dá inicializovať len cez ten nadefinovaný konštruktor. Ale už ho neviem inicializovať tak ako pred tým:
auto ti = FileTimesInfo{ .LastAccessTime = 0, .LastModificationTime = 0, .LastStatusChangeTime = 0 };
Prečo to tak je? a ako tento problém napraviť tak aby som mohol inicializovať triedu oboma spôsobmi? Aj cez custom konštruktor aj cez inializátor? Teraz si len domýšlam... moj predpoklad je že keď v C++ nenadefinujem žiadny konštruktor C++ nadefinuje nejaký implicitný defaultný konštruktor, ktorý umožňuje atribúty inicializovať priamo cez inicializátor. keď ale explicitne nadefinujem konštruktor prídem o ten implicitný ktorý C++ vytvára automaticky. Ako teda triede definovať custom konštruktor pričom nechcem prísť aj o tú formu priamej inicuializácie cez membery? Vopred ďakujem za vysvetlenie.
-
Bohužel nelze kombinovat uživatelský konstruktor a inicializaci jako v C (aggregate initialization).
https://en.cppreference.com/w/cpp/language/aggregate_initialization (https://en.cppreference.com/w/cpp/language/aggregate_initialization)
An aggregate is one of the following types:
class type (typically, struct or union), that has
no user-declared or inherited constructors
Šlo by to obejít vytvořením statické metody místo konstruktoru, např.:
struct FileTimesInfo
{
const __time64_t LastAccessTime;
const __time64_t LastModificationTime;
const __time64_t LastStatusChangeTime;
constexpr static FileTimesInfo create(const struct _stati64& stat) noexcept
{
return FileTimesInfo{
.LastAccessTime = stat.st_atime,
.LastModificationTime = stat.st_mtime,
.LastStatusChangeTime = stat.st_ctime
};
}
};
-
Potřebujete constructor, co bere std::initializer_list.
-
Bohužel nelze kombinovat uživatelský konstruktor a inicializaci jako v C (aggregate initialization).
https://en.cppreference.com/w/cpp/language/aggregate_initialization (https://en.cppreference.com/w/cpp/language/aggregate_initialization)
An aggregate is one of the following types:
class type (typically, struct or union), that has
no user-declared or inherited constructors
Šlo by to obejít vytvořením statické metody místo konstruktoru, např.:
struct FileTimesInfo
{
const __time64_t LastAccessTime;
const __time64_t LastModificationTime;
const __time64_t LastStatusChangeTime;
constexpr static FileTimesInfo create(const struct _stati64& stat) noexcept
{
return FileTimesInfo{
.LastAccessTime = stat.st_atime,
.LastModificationTime = stat.st_mtime,
.LastStatusChangeTime = stat.st_ctime
};
}
};
Vďaka za tento hack príznam sa že ma to ani nenapadlo aj keď som to v iných jazykoch občas používal. A ďakujem aj za informáciu, že to nejde, ostáva len dúfať že to zase opravia v > 20 verzii C++. V iných jazykoch sa objekty takto dajú bežne inicializovať a funguje to aj keď majú custom konštruktor, napr. C#:
class SomeComponent
{
public string Status { get; private set; }
public bool IsEnabled { get; set; }
public SomeComponent(string status)
{
Status = status;
IsEnabled = false;
}
public void DisplayStatus()
{
Console.WriteLine(
IsEnabled
? "Enabled with status: " + Status
: "Disabled"
);
}
}
var abc = new SomeComponent("Abc") { IsEnabled = true };
abc.DisplayStatus();
[quote author=mjakl link=topic=23970.msg341350#msg341350 date=1607508960]
Potřebujete constructor, co bere std::initializer_list.
[/quote]
Initializer list má template parameter a keď chcete inicializovať viac typov tak čo mu predáte? Okrem toho skúšal som to a nepodarilo sa mi to zfunkčniť takým spôsobom ako som načrtol v prvom poste.
-
Pokud chcete různé typy, tak můžete použít třeba tuple.