1 pièce(s) jointe(s)
Destruction d'objets dans une classe template
Bonjour,
Dans mon code, j'ai un pool d'objets alloués statiquement. J'ai une fonction emplace() pour réserver un slot et faire un placement new sur un élément du pool. J'ai une fonction release() qui fait un appel au destructeur d'un élément et relâcher le slot.
Pour simplifier, j'ai fait ce code qui est en fait un pool avec un seul élément mais qui permet de bien représenter mon contexte :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| #include <iostream>
template<typename T>
class Pool {
public:
void release() {
if (used_m) {
t_m.~T();
used_m = false;
}
}
template<typename ... Args>
void emplace(Args&& ... args) {
if (not used_m) {
new(&t_m) T{std::forward<Args>(args)...};
used_m = true;
}
}
private:
bool used_m = false;
T t_m{};
};
class A {
public:
A() {
std::cout << __PRETTY_FUNCTION__ << '\n';
}
A(int i, float f) {
std::cout << __PRETTY_FUNCTION__ << ' ' << i << ' ' << f << '\n';
}
~A() {
std::cout << __PRETTY_FUNCTION__ << '\n';
}
};
int main() {
Pool<A> pa;
pa.emplace(42, 3.14f);
pa.release();
Pool<int> pi;
pi.emplace(42);
pi.release();
} |
Sortie console lors de l'exécution :
$ untitled.exe
A::A()
A::A(int, float) 42 3.14
A::~A()
A::~A()
Process finished with exit code 0
Jusque là, tout me semble OK. Cette discussion stackoverflow me fait comprendre que mon code est valide : https://stackoverflow.com/questions/...s-int-char-etc
En revanche, si je change mon main() :
Code:
1 2 3 4 5
| int main() {
Pool<int[16]> pia;
pia.emplace(42, 66, 99);
pia.release(); // ceci est à la ligne 44
} |
alors mon code ne compile plus :
Code:
1 2 3 4 5 6
| [ 50%] Building CXX object CMakeFiles/untitled.dir/main.cpp.obj
main.cpp: In instantiation of 'void Pool<T>::release() [with T = int [16]]':
main.cpp:44:14: required from here
main.cpp:8:9: error: request for member '~int [16]' in '((Pool<int [16]>*)this)->Pool<int [16]>::t_m', which is of non-class type 'int [16]'
t_m.~T();
~~~~~^ |
CLion me met aussi une indication d'erreur sur cette ligne :
Pièce jointe 536761
Une recherche me confirme que le problème vient bien du fait que T est un tableau et non un scalar type.
Je me pose des questions sur la meilleure solution pour éviter cette erreur de compilation.
J'ai d'abord pensé à quelque chose comme :
Code:
1 2 3 4 5 6 7 8
| void release() {
if (used_m) {
if constexpr (std::is_destructible_v<T>) {
t_m.~T();
}
used_m = false;
}
} |
Mais cela ne fonctionne pas car le code est toujours compilé.
Vous avez des idées à me proposer ? Merci d'avance ! :ccool: