Информация об изменениях

Сообщение ? Зачем виртуальный метод запрещает структурную инициализаци от 22.08.2023 17:36

Изменено 22.08.2023 18:32 Sm0ke

? Зачем виртуальный метод запрещает структурную инициализаци
Вот есть простые структуры. Без явных конструкторов.
Как же удобно для них создавать объекты с почленной инициализацией.
Хочешь все укажи, хочешь некоторые.
С 20-ым стандартом можно по имени свойства значения задавать. (aka designated)

#include <iostream>

using t_diff = std::ptrdiff_t;

struct t_param
{
  // data
  t_diff
    count{};
  bool
    flag{};

  //virtual void no() const {}
};

int main()
{
  t_param o{1};
  t_param p{.flag = true}; // designated / by prop name
  return 0;
}


Но стоит только туда добавить хоть один виртуальный метод ...
... И всё! Для инициализации полей пиши конструктор


Зачем они так?
Даже не-виртуальный деструктор картины не портит.
Что не так с виртуальными методами? Не вижу смысла запрещать прежнюю инициализацию с ними!

#include <iostream>

using t_diff = std::ptrdiff_t;

struct t_param
{
  // data
  t_diff
    count{};
  bool
    flag{};

  virtual void no() const {}
};

int main()
{
  t_param o{1};
  t_param p{.flag = true};
  return 0;
}


x86-64 clang 13.0.0 (Editor #1)

x86-64 clang 13.0.0
x86-64 clang 13.0.0
see detailed flags window
123
<Compilation failed>

# For more information see the output window
x86-64 clang 13.0.0 — cached
Output of x86-64 clang 13.0.0 (Compiler #1)
<source>:18:11: error: no matching constructor for initialization of 't_param'
t_param o{1};
^~~~
<source>:5:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const t_param' for 1st argument
struct t_param
^
<source>:5:8: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 't_param' for 1st argument
struct t_param
^
<source>:5:8: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided
<source>:19:11: error: no matching constructor for initialization of 't_param'
t_param p{.flag = true};
^~~~~~~~~~~~~~~
<source>:5:8: note: candidate constructor (the implicit copy constructor) not viable: cannot convert argument of incomplete type 'void' to 'const t_param' for 1st argument
struct t_param
^
<source>:5:8: note: candidate constructor (the implicit move constructor) not viable: cannot convert argument of incomplete type 'void' to 't_param' for 1st argument
struct t_param
^
<source>:5:8: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided
2 errors generated.
Compiler returned: 1

? Зачем виртуальный метод запрещает структурную инициализаци
Вот есть простые структуры. Без явных конструкторов.
Как же удобно для них создавать объекты с почленной инициализацией.
Хочешь все укажи, хочешь некоторые.
С 20-ым стандартом можно по имени свойства значения задавать. (aka designated)

#include <iostream>

using t_diff = std::ptrdiff_t;

struct t_param
{
  // data
  t_diff
    count{};
  bool
    flag{};

  //virtual void no() const {}
};

int main()
{
  t_param o{1};
  t_param p{.flag = true}; // designated / by prop name
  return 0;
}


Но стоит только туда добавить хоть один виртуальный метод ...
... И всё! Для инициализации полей пиши конструктор


Зачем они так?
Даже не-виртуальный деструктор картины не портит.
Что не так с виртуальными методами? Не вижу причины запрещать прежнюю инициализацию с ними!

#include <iostream>

using t_diff = std::ptrdiff_t;

struct t_param
{
  // data
  t_diff
    count{};
  bool
    flag{};

  virtual void no() const {}
};

int main()
{
  t_param o{1};
  t_param p{.flag = true};
  return 0;
}


x86-64 clang 13.0.0 (Editor #1)

x86-64 clang 13.0.0
x86-64 clang 13.0.0
see detailed flags window
123
<Compilation failed>

# For more information see the output window
x86-64 clang 13.0.0 — cached
Output of x86-64 clang 13.0.0 (Compiler #1)
<source>:18:11: error: no matching constructor for initialization of 't_param'
t_param o{1};
^~~~
<source>:5:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const t_param' for 1st argument
struct t_param
^
<source>:5:8: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 't_param' for 1st argument
struct t_param
^
<source>:5:8: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided
<source>:19:11: error: no matching constructor for initialization of 't_param'
t_param p{.flag = true};
^~~~~~~~~~~~~~~
<source>:5:8: note: candidate constructor (the implicit copy constructor) not viable: cannot convert argument of incomplete type 'void' to 'const t_param' for 1st argument
struct t_param
^
<source>:5:8: note: candidate constructor (the implicit move constructor) not viable: cannot convert argument of incomplete type 'void' to 't_param' for 1st argument
struct t_param
^
<source>:5:8: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided
2 errors generated.
Compiler returned: 1