В моей библиотеке С++ JSON у меня недавно была регрессия с GCC7. Я удалил поврежденный код и надеюсь понять ошибку.
Код
Рассмотрим этот заголовок 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 = {};
};
Как вы видите, я использовал имя "array" как имя переменной-члена в struct value_t
, как имя статической функции. Затем я включил заголовок в следующий файл:
#include <array>
using std::array; // note this!
#include "myclass.hpp"
int main()
{}
Проблема
Код компилируется с помощью GCC6 и Clang5 (используя -std=c++11
), но GCC7 сообщает:
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
Кажется, что парсер читает "массив" в lhs.val.array
как std::array
и рассматривает следующий <
как начало списка шаблонов.
Код можно скомпилировать, если я сделаю любое из следующих изменений:
- Удалите
using std::array;
или переместите его за#include "myclass.hpp"
. - Измените
return lhs.val.array < rhs.val.array;
наreturn (lhs.val.array) < rhs.val.array;
.
Кроме того, сбой компилятора, если я удаляю функцию static A array()
...
Мои вопросы
- Является ли код правильным в первую очередь? Могу ли я использовать "массив" в качестве имени, даже если я использую
using std::array;
? - Если код верен, это ошибка в GCC7?