LINUX.ORG.RU

незнакомый синтаксис c++ в glibmm

 


0

2

#незнакомый синтаксис c++ в glibmm

У меня есть приложение, написанное с применением gtkmm. Без проблем собирается как g++, так и clang++ со всеми флагами стандарта, вплоть до -std=c++17. Однако на g++-11.2 с флагом -std=c++20 компиляция завершается с ошибкой:

/usr/include/glibmm-2.4/glibmm/variant.h:956:24: error: expected unqualified-id before ‘)’ token
  956 |   Variant<VariantBase>();
      |                        ^
compilation terminated due to -Wfatal-errors.

Ошибка указывет конструктор glibmm-вского класса Variant. Класс объявлен так:

template<>
class GLIBMM_API Variant<VariantBase> : public VariantContainerBase
{
public:
  using CType = GVariant*;
  using CppType = VariantBase;
  using CppContainerType = Variant<VariantBase>;

  /// Default constructor.
  Variant<VariantBase>();

   и т.д.

Там еще много разных специализаций Variant для разных типов с таким синтаксисом объявления конструктора:

template<>
class GLIBMM_API Variant<Glib::ustring> : public VariantStringBase
{
public:
  using CType = char*;
  using CppType = Glib::ustring;

  /// Default constructor.
  Variant<Glib::ustring>();

...

Вопрос: что это за синтаксис конструктора и почему он не собирается с 20-м стандартом?


это синтаксис марсианских наркоманов с юпитера. он не собирается потому что компилятор писали юпитерские наркоманы с марса

anonymous
()
Ответ на: комментарий от gag

Версия glibmm 2.64.2. Этот фикс видимо будет в следующей версии. Но интересно еще для чего нужен такой синтаксис конструктора.

jban
() автор топика
Ответ на: комментарий от anonymous

Кстати clang-13 собирает этот код без проблем с -std=c++20.

jban
() автор топика
Ответ на: комментарий от gag

Ну, смотрим в C++20 [class.ctor]/1:

A constructor is introduced by a declaration whose declarator is a function declarator of the form … and the id-expression has one of the following forms:
— in a member-declaration that belongs to the member-specification of a class or class template but is not a friend declaration ([class.friend]), the id-expression is the injected-class-name ([class.pre])

Открываем [class.pre]/2:

A class-name is inserted into the scope in which it is declared immediately after the class-name is seen. The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name.

Из [class.pre]/1:

class-name:

  • identifier
  • simple-template-id

В случае template<> class Variant<VariantBase>, class-name это Variant<VariantBase> и согласно [class.pre]/2 является injected-class-name. Согласно [class.ctor]/1, injected-class-name МОЖЕТ использоваться при объявлении конструктора.

Т.е. Variant<VariantBase>() это валидное объявление конструктора в C++20.

anonymous
()
Ответ на: комментарий от anonymous

А для чего используется таким образом объявленный конструктор? Чем он отличается от

template<>
class Variant<Glib::ustring> : public VariantStringBase
{
public:
  Variant();
jban
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.