Зависит ли доступ к переменным-членам в случае нескольких компиляторов Inheritance? Как это сделать правильно?

Я имею для следующей ситуации:

template <class K> class A
{
public:
int a;
};

class B
{
public:
virtual void DoSomething() = 0;
};template <class K> class C : public A<K>, public B
{
public:
virtual void DoSomething()
{
a = 3;      // ***
}
};

Теперь это работает на MSVC, однако gcc сообщает мне строку с 3 звездами: «ошибка:« a »не было объявлено в этой области». Я понял, что могу заменить строку на

A::a = 3;

и это работает на GCC (хорошо MINGW), а также. Нужно ли постоянно добавлять исходное имя класса для соответствия стандарту? Я думал, я должен добавить его, только если имена конфликтуют иначе.

Я использую mingw32 (gcc) 4.8.1.

1

Решение

Теперь это имеет смысл …

GCC прав, а MSVC не прав. Это не должно работать, потому что a является зависимый от шаблона но выражение a; не является.

То есть смысл, который вы намереваетесь a зависит от аргумента шаблона (в вашем случае K), но содержащееся в нем выражение — нет. И так как компилятор не может быть уверен, что создание экземпляров A<K> будет иметь член по имени aЭто просто предполагает, что это не так.

Есть несколько простых решений, все они включают использование зависимого от шаблона выражения, поэтому решите a:

this->a = 3; //my favourite
A<K>::a = 3; //you found this one

ПРИМЕР:

Давайте посмотрим пример того, почему это не должно работать:

template <typename K> struct A
{
int a;
};

int a; //global variable to make things more interesting

template <typename K> struct B : A<K>
{
void foo()
{
a = 3; //does it refer to A<K>::a or ::a?
}
};

//template specialization of A<int>
template <> struct A<int>
{
};

B<float> bf; // what does bf.foo() do?
B<int> bi; //and bi.foo()?

Также вы можете сделать противоположную ситуацию:

template <typename K> struct A
{
};

int a; //global variable to make things more interesting

template <typename K> struct B : A<K>
{
void foo()
{
a = 3; //does it refer to A<K>::a or ::a?
}
};

//template specialization of A<int>
template <> struct A<int>
{
int a; //now the member variable is in the specialization
};

B<float> bf; // what does bf.foo() do?
B<int> bi; //and bi.foo()?

Как вы можете видеть, стандартное поведение C ++ обеспечивает вашу защиту, поэтому код, который вы пишете в шаблоне, всегда будет ссылаться — более или менее — на одно и то же:

  • a: всегда будет переменной non template (в данном случае глобальной), если она доступна. Если нет, то это ошибка компилятора.
  • this->a: всегда будет переменной-членом, если она доступна. Если нет, ошибка компилятора.
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]