Les compilateurs (clang-5.0.0
, GCC-7.3
, ICC-18
et MSVC-19
) divergent w.r.t. l'accessibilité des membres de l' A
ci-dessous.
class A {
template <class> static constexpr int f() { return 0; }
template <int> struct B {};
template <class T> using C = B<f<T>()>;
};
En effet, considérer les points suivants usages:
template <class T> using D = A::C<T>;
int main() {
// | clang | gcc | icc | msvc
(void) A::f<int>(); // 1: | f | f | f | f, (C)
(void) A::B<0>{}; // 2: | B | | B | B, (C)
(void) A::C<int>{}; // 3: | C, f | | C | C
(void) D<int>{}; // 4: | f | | C | C
}
Le tableau de droite indique les membres de chaque compilateur, qui nécessite d'être rendue publique à accepter le code (lorsqu'il est compilé en C++14).
À mon humble avis, la cour et le MSVC (en ignorant (C)
des entrées) semblent corrects. Sauf pour la première ligne, GCC semble être complètement ignorant de l'accessibilité.
Je suis en désaccord avec clang quand il exige f
publics pour instancier A::C<int>
et D<int>
. Comme CPI et MSVC, je pense que C
et seulement C
doit être public. Il est vrai que l' C
utilise f
mais n'est-il pas un détail d'implémentation? Notez que C
utilise également B
. Si clang étaient correctes, alors pourquoi n'est-il pas exiger B
publics ainsi?
Enfin, permettez-nous de considérer l' (C)
des entrées. MSVC exige C
publics, quand il rencontre d'abord la définition de l' D
, qui est, MSVC se plaint C
étant privés.
Mes questions sont les suivantes:
- Suis-je le droit (et est donc CPI) dans mon analyse? Sinon, qui d'autre compilateur est correct, et pourquoi?
- Est le MSVC encore d'une autre incarnation de deux phases de l'instanciation d'un bug dans msvc?
Mise à jour: en ce qui Concerne GCC, ce qui semble être le bug signalé dans le commentaire 8, ici.