Bug de compilador com parâmetro de modelo = vazio*

 

Erro de compilador. Bild 1961, 64 bit.

template<typename T>
class A
{ 
};

A<void*> a;  // '<' - cannot to apply function
 
Isso era possível antes?
 
Vou verificar este anúncio com C++ à noite
 
Vladimir Simakov:
Isso era possível antes?

Sim. Verifiquei especialmente na construção antiga (1554) - tudo funciona.

Vou verificar isso hoje à noite com tal anúncio em C++.

Bem, certamente está tudo bem aí. Há alguma razão para que possa não funcionar?
 
Alexey Navoykov:

Por favor, dê um exemplo do uso desta construção.

 
fxsaber:

Por favor, dê um exemplo de como utilizar esta construção.

O exemplo mais trivial é uma classe de array. Neste caso, ela é usada para armazenar quaisquer indicações:

template<typename T>
class CArray
{
  T _data[]; 
 public:
  T operator[](int i) const { return _data[i]; }
  int Size()          const { return ArraySize(_data); }
  // и т.д.
};

СArray<void*> pointers;
 
Alexey Navoykov:

O exemplo mais trivial é a classe da matriz. Neste caso, ela é usada para armazenar quaisquer indicações.

Como utilizá-lo então?

class A
{
public:
  void OnInit()
  {
    Print(__FUNCSIG__);
  }
};

class B
{
public:
  void OnInit()
  {
    Print(__FUNCSIG__);
  }
};

void OnStart()
{    
  void* Pointers[2];

  A a;
  B b;
  
  Pointers[0] = &a;
  Pointers[1] = &b;
  
  for (int i = 0; i < ArraySize(Pointers); i++)
    Pointers[i].OnInit(); // 'OnInit' - member function not defined
}
 
fxsaber:

Como utilizá-lo então?

Da mesma forma que, por exemplo, o CObject é usado em contêineres de metaquota. Você atira para o tipo que colocou inicialmente (ou verifica com dynamic_cast). É um pouco surpreendente ouvir você perguntar isso.
 
Alexey Navoykov:
Fundido ao tipo que você colocou ali originalmente (ou verifique via dynamic_cast).
//    (A*)Pointers[i].OnInit();
    ((A*)Pointers[i]).OnInit();

Isto é apenas sobre se os parênteses são necessários/desnecessários... Com este casting, seria uma chatice no roteiro acima quando executado. Isto é, você precisa saber os nomes das classes às quais os elementos do ponteiro da matriz se referem.

Não vejo qual é então a conveniência.


A MQ só usa o vazio* em um só lugar.

typedef string(*DoubleToStringFunction)(double,void*);
 
fxsaber:

A MQ só usa o vazio* em um só lugar.

Como eles têm tudo construído sobre CObject, é impossível usar seus recipientes para suas próprias classes e interfaces, não herdados de sua classe, ou seja, não uma solução universal.

Isto provavelmente se deve ao fato de que no momento da criação de sua biblioteca ainda não havia vazio* na MQL. Mas, por outro lado, seu próprio objeto também participa de algumas manipulações (alterando valores de ponteiros nela), o que por si só é simplesmente selvagem.

 
Alexey Navoykov:

Isto torna impossível a utilização de seus recipientes para suas próprias classes e interfaces não herdadas de sua classe, ou seja, não uma solução universal.

Talvez isto se deva ao fato de que, na época em que sua biblioteca foi criada, ainda não havia nenhum vazio* na MQL.

Infelizmente, ainda não vi um exemplo de seu uso.

Razão: