Il est un cas limite où statique a une surprenante touche (au moins c'était pour moi). Le C++03 Standard unis dans 14.6.4.2/1:
Pour un appel de fonction qui dépend d'un paramètre du modèle, si le nom de la fonction est un unqualified-id , mais pas un modèle-id, le candidat fonctions sont trouvés à l'aide de l'habitude, les règles de recherche (3.4.1, 3.4.2), sauf que:
- Pour la partie de la recherche de l'aide inconditionnelle de recherche de nom (3.4.1), seules les déclarations de fonction avec une liaison externe à partir de la définition de modèle de contexte sont trouvés.
- Pour la partie de la recherche de l'aide associée à des espaces de noms (3.4.2), seules les déclarations de fonction avec une liaison externe trouvée dans la tmeplate définition du contexte ou de l'instanciation du modèle de contexte sont trouvés.
...
Le code ci-dessous appellera foo(void*)
et pas foo(S const &)
comme vous vous en doutez.
template <typename T>
int b1 (T const & t)
{
foo(t);
}
namespace NS
{
namespace
{
struct S
{
public:
operator void * () const;
};
void foo (void*);
static void foo (S const &); // Not considered 14.6.4.2(b1)
}
}
void b2()
{
NS::S s;
b1 (s);
}
En soi, ce n'est probablement pas un gros problème, mais elle met en évidence que, pour un entièrement conforme compilateur C++ (c'est à dire. celui avec le soutien de export
) static
mot clé sera toujours avoir une fonctionnalité qui n'est pas disponible de toute autre manière.
// bar.h
export template <typename T>
int b1 (T const & t);
// bar.cc
#include "bar.h"
template <typename T>
int b1 (T const & t)
{
foo(t);
}
// foo.cc
#include "bar.h"
namespace NS
{
namespace
{
struct S
{
};
void foo (S const & s); // Will be found by different TU 'bar.cc'
}
}
void b2()
{
NS::S s;
b1 (s);
}
La seule façon de s'assurer que la fonction de notre sans nom d'espace de noms ne seront pas trouvés dans les modèles à l'aide de l'ADL est de rendre l' static
.