Dans mon C++ librairie JSON, j'ai récemment eu une régression avec GCC7. J'ai démonté le code affecté et l'espoir de comprendre l'erreur.
Le code
Considérer cet en-tête myclass.hpp
:
#pragma once
template <typename X>
struct A
{
struct value_t
{
X array;
};
static A array()
{
return A();
}
friend bool operator<(const A& lhs, const A& rhs) noexcept
{
return lhs.val.array < rhs.val.array;
}
value_t val = {};
};
Comme vous le voyez, j'ai utilisé le nom de "tableau" comme nom de variable membre struct value_t
, comme le nom d'une fonction statique. J'ai alors compris l'en-tête dans le fichier suivant:
#include <array>
using std::array; // note this!
#include "myclass.hpp"
int main()
{}
Le problème
Le code se compile avec GCC6 et Clang5 (à l'aide d' -std=c++11
), mais GCC7 rapports:
In file included from example.cpp:3:0:
myclass.hpp: In function 'bool operator<(const A<X>&, const A<X>&)':
myclass.hpp:19:40: error: wrong number of template arguments (1, should be 2)
return lhs.val.array < rhs.val.array;
^~~~~
In file included from example.cpp:1:0:
/usr/local/Cellar/gcc/7.1.0/include/c++/7.1.0/array:94:12: note: provided for 'template<class _Tp, long unsigned int _Nm> struct std::array'
struct array
^~~~~
make: *** [all] Error 1
Il me semble que si l'analyseur lit le "tableau" en lhs.val.array
comme std::array
et traite les suivantes <
comme le début d'une liste de modèle.
Le code peut être compilé si je fais les modifications ci-dessous:
- Supprimer l'
using std::array;
ou déplacer derrière#include "myclass.hpp"
. - Variation
return lhs.val.array < rhs.val.array;
dereturn (lhs.val.array) < rhs.val.array;
.
En outre, le compilateur ne parvient pas, si je retire l' static A array()
de la fonction...
Mes questions
- Le code est-il correct en premier lieu? Suis-je autorisé à utiliser le "tableau" comme un nom, même si j'utilise
using std::array;
? - Si le code est correct, est-ce un bug GCC7?