Proposition : équivalent de using namespace pour les fonctions statiques des classes
Bonjour,
Soit le code suivant :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #ifndef INCLUDED__MY_PROJECT__MATH__H
#define INCLUDED__MY_PROJECT__MATH__H
#include <cassert>
namespace MyProject {
class Math {
public:
static double sqrt(double x) {
assert(x >= 0);
const double result = sqrtImpl(x);
assert(result >= 0);
return result;
}
private:
static double sqrtImpl(double x);
};
}
#endif |
Dans mon exemple, les assert servent à vérifier la précondition et la postcondition, et aussi à les documenter, d'où leur présence dans "Math.h". Le détail de l'implémentation se trouve dans la définition de sqrtImpl, dans "Math.cpp".
Dans certains bouts de code utilisateur, pour raccourcir l'écriture MyProject::Math::sqrt, j'aimerais pouvoir aller plus loin que using namespace MyProject; et écrire using MyProject::Math::sqrt;, afin de pouvoir écrire directement sqrt.
De même, dans le cas où je fais appel à beaucoup de fonctions statiques de MyProject::Math, j'aimerais pouvoir écrire quelque chose comme using class MyProject::Math; pour pouvoir utiliser directement ces fonctions sans préfixe.
Mais le code suivant n'est pas valide en C++ :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| int main()
{
{
using class MyProject::Math;
std::cout << sqrt(9); // Erreur de compilation
}
{
using MyProject::Math::sqrt; // Erreur de compilation
std::cout << sqrt(16); // Erreur de compilation
}
return 0;
} |
Actuellement, en C++, le seul moyen de faire cela est de transformer MyProject::Math en espace de nom :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #ifndef INCLUDED__MY_PROJECT__MATH__H
#define INCLUDED__MY_PROJECT__MATH__H
#include <cassert>
namespace MyProject::Math {
namespace Private {
double sqrtImpl(double x);
}
double sqrt(double x) {
assert(x >= 0);
const double result = Private::sqrtImpl(x);
assert(result >= 0);
return result;
}
}
#endif |
Le problème, c'est que l'on perd la fonctionnalité private. En effet, l'utilisateur peut appeler MyProject::Math::Private::sqrtImpl.
Au début, j'avais pensé à ajouter au C++ la possibilité d'utiliser private dans un espace de nom :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #ifndef INCLUDED__MY_PROJECT__MATH__H
#define INCLUDED__MY_PROJECT__MATH__H
#include <cassert>
namespace MyProject::Math {
private:
double sqrtImpl(double x);
public:
double sqrt(double x) {
assert(x >= 0);
const double result = sqrtImpl(x);
assert(result >= 0);
return result;
}
}
#endif |
Mais, contrairement aux classes, les espaces de nom sont extensibles, ce qui permet à l'utilisateur d'écrire :
Code:
1 2 3 4 5
| namespace MyProject::Math {
double triche(double x) {
return sqrtImpl(x);
}
} |
et d'appeler directement la fonction triche.
Du coup, je préfère la possibilité d'avoir l'équivalent de using namespace pour les fonctions statiques des classes.
Seriez-vous d'accord pour l'ajout d'une telle fonctionnalité au langage C++ ?