Ответ 1
template <typename F> class S : C<A, F>
^
Вы не указываете наследование public
, поэтому по умолчанию оно private
, что делает базовые классы недоступными.
Я пытаюсь вызвать функцию класса A<F>::f()
из класса S
, но я получаю следующие ошибки, когда я создаю объект S
(S<int>s
) и вызываю его f
member function (s.f()
):
source.cpp: при создании '
int S<F>::f() [with F = int]
':
source.cpp: 30: 21: требуется отсюда
source.cpp: 22: 25: ошибка: 'A<int>
' не является доступной базой 'S<int>
'
Обратите внимание, что это работает, когда я заменяю return A<F>::f();
внутри объявления класса S
на return C<A, F>::f();
. Но мне интересно, почему я не могу сделать это по-другому...
#include <iostream>
template <typename T> class A {
public:
int f();
};
template <typename T> int A<T>::f() {
return sizeof(T);
}
template <template <typename> class E, typename D> class C : E<D> {
public:
int f() {
return E<D>::f();
}
};
template <typename F> class S : C<A, F> {
public:
int f() {
return A<F>::f();
}
};
int main() {
S<int>s;
std::cout << s.f();
}
Любая помощь приветствуется, и если вам потребуются дополнительные разъяснения, пожалуйста, не стесняйтесь комментировать.
Обновление
Поскольку эти вопросы решены, я думаю, я должен опубликовать код, который действительно работал:
#include <iostream>
template <typename T> class A {
public:
int f();
};
template <typename T> int A<T>::f() {
return sizeof(T);
}
template <template <typename> class E, typename D> class C : public E<D> {
public:
int f() {
return E<D>::f();
}
};
class S : public C<A, int> {};
int main() {
S s;
std::cout << s.f(); // 4
}
template <typename F> class S : C<A, F>
^
Вы не указываете наследование public
, поэтому по умолчанию оно private
, что делает базовые классы недоступными.
Я думаю, что это просто вопрос использования наследования класса public
. Попробуйте:
template <template<class> class E, typename D> class C : public E<D> {
public:
int f() {
return E<D>::f();
}
};
template <typename F> class S : public C<A, F> {
public:
int f() {
return A<F>::f();
}
};
Когда вы пытаетесь вызвать A
версию f()
, вы используете обозначение A<F>::f()
. Если A<F>
имеет функцию члена static
f()
, эту функцию действительно вызывали. Однако A<F>
имеет только функцию f()
не static
, т.е. Вызов неявно переводится на this->A<F>::f()
. Однако S<F>
не имеет A<F>
в качестве доступной базы (это база private
C<A, F>
). По внешнему виду вы хотите делегировать C<A, F>
версию f()
:
C<A, F>::f();
который должен работать, потому что C<A, F>
является доступной базой S<int>
или сделать базу E<D>
C
доступной, сделав ее либо public
, либо protected
.