Проблема GCC: использование члена базового класса, который зависит от аргумента шаблона

Ваш URL-адрес данных состоит из большого количества ссылок на внешние изображения, такие как

<image preserveAspectRatio="none" x="310.15625" y="281" width="256px" height="256px" xlink:href="http://ecn.t0.tiles.virtualearth.net/tiles/r311213001300102.jpeg?g=5171&amp;mkt=en-US&amp;shading=hill" clip-path="url(#kdef7)" />

. При использовании в качестве изображения в вашем случае с помощью тега изображения SVG должен состоять из одного файла, чтобы вы вам придется кодировать каждое из этих изображений в виде URL-адресов данных, а затем после того, как вы сделали это, перекодируйте весь файл SVG в качестве URL-адреса данных.

34
задан hmatar 18 March 2017 в 19:06
поделиться

5 ответов

Это изменилось в gcc-3.4. Синтаксический анализатор C++ стал намного более строгим в том выпуске - на спецификацию, но все еще довольно раздражающий для людей с или многоплатформенными кодовыми базами прежней версии.

11
ответ дан David Joyner 27 November 2019 в 16:29
поделиться

У David Joyner была история, вот причина.

проблема при компиляции B<T> состоит в том, что ее базовый класс A<T> неизвестен из компилятора, будучи шаблонным классом, таким образом, никакой путь к компилятору для знания любых участников от базового класса.

Более ранние версии сделали некоторый вывод путем фактического парсинга основного шаблонного класса, но C++ ISO указал, что этот вывод может привести к конфликтам, где не должно быть.

решение сослаться на участника базового класса в шаблоне состоит в том, чтобы использовать this (как Вы, сделал), или конкретно назовите базовый класс:

template <typename T> class A {
public:
    T foo;
};

template <typename T> class B: public A <T> {
public:
    void bar() { cout << A<T>::foo << endl; }
};
[еще 119] информация в gcc руководство .

34
ответ дан SirGuy 27 November 2019 в 16:29
поделиться

Ничего себе. C++ никогда не прекращает удивлять меня своей странностью.

В шаблонном определении, дисквалифицированные имена больше не будут находить членов зависимой основы (как определено [temp.dep]/3 в стандарте C++). Например,

template <typename T> struct B {
  int m;
  int n;
  int f ();
  int g ();
};
int n;
int g ();
template <typename T> struct C : B<T> {
  void h ()
  {
    m = 0; // error
    f ();  // error
    n = 0; // ::n is modified
    g ();  // ::g is called
  }
};

необходимо сделать зависимого имен, например, путем добавления префикса их это->. Вот исправленное определение C:: h,

template <typename T> void C<T>::h ()
{
  this->m = 0;
  this->f ();
  this->n = 0
  this->g ();
}

Как альтернативное решение (к сожалению, не назад совместимый с GCC 3.3), можно использовать объявления использования вместо этого->:

template <typename T> struct C : B<T> {
  using B<T>::m;
  using B<T>::f;
  using B<T>::n;
  using B<T>::g;
  void h ()
  {
    m = 0;
    f ();
    n = 0;
    g ();
  }
};

Это - просто все виды сумасшедших. Спасибо, David.

Вот "temp.dep/3" раздел стандарта [ISO/IEC 14882:2003], к которому они обращаются:

В определении шаблона класса или члене шаблона класса, если базовый класс шаблона класса зависит от шаблонного параметра, объем базового класса не исследован во время неполного поиска имени или при определении шаблона класса или при участнике или во время инстанцирования шаблона класса или участника. [Пример:

typedef double A; 
template<class T> class B { 
    typedef int A; 
}; 
template<class T> struct X : B<T> { 
    A a; // a has typedouble 
}; 

имя типа A в определении X<T> связывает с именем определения типа, определенным в объеме глобального пространства имен, не к имени определения типа, определенному в базовом классе B<T>.] [Пример:

struct A { 
    struct B { /* ... */ }; 
    int a; 
    int Y; 
}; 
int a; 
template<class T> struct Y : T { 
    struct B { /* ... */ }; 
    B b; //The B defined in Y 
    void f(int i) { a = i; } // ::a 
    Y* p; // Y<T> 
}; 
Y<A> ya; 

участники A::B, A::a, и A::Y из аргумента шаблона A не влияют на привязку имен в [1 112].]

19
ответ дан Derek Park 27 November 2019 в 16:29
поделиться

Главная причина C++ ничего не может принять здесь, состоит в том, что основной шаблон может быть специализирован для типа позже. Продолжение исходного примера:

template<>
class A<int> {};

B<int> x; 
x.bar();//this will fail because there is no member foo in A<int>
8
ответ дан Matt Price 27 November 2019 в 16:29
поделиться

VC не делает реализованного двухфазного поиска, в то время как GCC делает. Таким образом, GCC анализирует шаблоны, прежде чем они инстанцируют, и таким образом находит больше ошибок, чем VC. В Вашем примере нечто является зависимым именем, так как это зависит от 'T'. Если Вы не говорите компилятор, куда он прибывает из, он не может проверить законность шаблона вообще перед инстанцированием его. Вот почему необходимо сказать компилятор, куда он прибывает из.

3
ответ дан hschober 27 November 2019 в 16:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: