Lors de l'écriture d'une classe pour l'encapsulation d'un objet affecté par un tas, j'ai rencontré un problème de conversion de type implicite qui peut être réduit à cet exemple simple.Impossible de trouver l'opérateur via une conversion implicite en C++
Dans le code ci-dessous, la classe wrapper gère un objet affecté par le tas et convertit implicitement en une référence à cet objet. Cela permet à l'objet wrapper d'être passé comme argument à la fonction write (...) puisque la conversion implicite a lieu.
Le compilateur échoue, cependant, en essayant de résoudre l'appel à l'opérateur < < (...), sauf si une distribution explicite est faite (vérifié avec les compilateurs MSVC8.0, Intel 9.1 et gcc 4.2.1). Donc, (1) pourquoi la conversion implicite échoue-t-elle dans ce cas? (2) pourrait-il être lié à la recherche dépendant de l'argument? et (3) est-ce qu'il y a quelque chose qui peut être fait pour faire ce travail sans la distribution explicite?
#include <fstream>
template <typename T>
class wrapper
{
T* t;
public:
explicit wrapper(T * const p) : t(p) { }
~wrapper() { delete t; }
operator T &() const { return *t; }
};
void write(std::ostream& os)
{
os << "(1) Hello, world!\n";
}
int main()
{
wrapper<std::ostream> file(new std::ofstream("test.txt"));
write(file);
static_cast<std::ostream&>(file) << "(2) Hello, world!\n";
// file << "(3) This line doesn't compile!\n";
}
Je manque complètement la valeur de wrapper: les objets fstream créés sur la pile nettoient après eux-mêmes. Au lieu de cela, vous créez un objet fstream sur le tas, puis en utilisant wrapper pour garantir qu'il est nettoyé exactement au même endroit où il aurait été nettoyé pour commencer. –
Dans la version réelle, j'utilise boost :: shared_ptr au lieu de T * afin que les instances soient partagées et implémente la sémantique nécessaire pour une instance partagée. L'exemple est grandement simplifié, et pas très réaliste, mais juste assez pour montrer le problème. –
l'ensemble des conversions est limité si les arguments d'un modèle sont auto-décu. donc dans votre cas si vous auriez un template void write (basic_ostream &); vous auriez le même problème (en plus de la recherche dépendant de l'argument dans l'op << cas) –