Подтвердить что ты не робот

Могут ли неназванные структуры наследовать?

Следующее выглядит как ошибка компиляции:

struct : Base { };

Тем не менее, когда используется [1] он работает:

#include <iostream>
using namespace std;

template<bool B>
struct A 
{
    struct : std::integral_constant<bool, B> {
    } members;
};

int main()
{
    A<true> a;    
    cout << a.members.value << endl;
    return 0;
}

В С++ допустимо ли для неназванных структур наследовать? Есть ли примеры, когда это доступно?


[1] Отказ от ответственности: я не притворяюсь, что приведенный пример полезен. Я редко использую неназванные структуры, и когда я это делаю, они обычно объединяют некоторые встроенные переменные-члены, чтобы обеспечить более чистый интерфейс для класса. Вопрос возник из-за того, что memberspaces не нужно называть структуры

4b9b3361

Ответ 1

Беззначные классы могут наследовать. Это полезно, например, в ситуациях, когда вы должны наследовать, чтобы переопределить виртуальную функцию, но вам не нужно больше одного экземпляра класса, и вам не нужно ссылаться на производный тип, потому что ссылка на базу типа.

Вот пример:

#include <iostream>
using namespace std;

struct Base {virtual int process(int a, int b) = 0;};
static struct : Base {
    int process(int a, int b) { return a+b;}    
} add;
static struct : Base {
    int process(int a, int b) { return a-b;}    
} subtract;
static struct : Base {
    int process(int a, int b) { return a*b;}    
} multiply;
static struct : Base {
    int process(int a, int b) { return a/b;}    
} divide;

void perform(Base& op, int a, int b) {
    cout << "input: " << a << ", " << b << "; output: " << op.process(a, b) << endl;
}

int main() {
    perform(add, 2, 3);
    perform(subtract, 6, 1);
    perform(multiply, 6, 7);
    perform(divide, 72, 8);
    return 0;
}

Этот код создает четыре анонимных вывода Base - по одному для каждой операции. Когда экземпляры этих дериваций передаются функции perform, вызывается соответствующее переопределение. Обратите внимание, что perform не нужно знать ни о каком конкретном типе - базового типа с его виртуальной функцией достаточно для завершения процесса.

Вот результат выполнения приведенного выше кода:

input: 2, 3; output: 5
input: 6, 1; output: 5
input: 6, 7; output: 42
input: 72, 8; output: 9

Демо на идеоне.

Ответ 2

Ваш первый пример, потому что он ничего не объявляет, показывает попытку анонимной структуры (которая не разрешена - 7/3), а не неназванной (которая есть).

Грамматика в 9/1 стандарта С++ 11, по-видимому, позволяет безымянному классу иметь базу, поэтому я думаю, что ваш второй пример в порядке.