Bonjour,

Soit le code suivant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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++ ?