テンプレート・パラメータ = void* のコンパイラ・バグ

 

コンパイラーエラー。 Bild 1961, 64 bit.

template<typename T>
class A
{ 
};

A<void*> a;  // '<' - cannot to apply function
 
以前は可能だったのでしょうか?
 
この発表については、夕方にC++で確認します
 
Vladimir Simakov:
以前は可能だったのでしょうか?

はい、古いビルド(1554)で特別にチェックしましたが、すべてうまくいきました。

今夜、C++でこのような発表をして確認します。

確かにそこは大丈夫なのですが、うまくいかない理由はあるのでしょうか?
 
Alexey Navoykov:

この構造の使用例を教えてください。

 
fxsaber:

この構成の使い方の例を教えてください。

最も単純な例は配列クラスです。 この場合、任意のポインタを格納するために使用されます。

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:

最も単純な例は、配列クラスです。 この場合、任意のポインタを格納するために使用されます。

では、どのように使うのか。

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:

では、どのように使うのか。

メタクオートコンテナでCObjectなどを 使うのと同じです。 最初に置いた型にキャストする(またはdynamic_castで確認する)。 この質問をされるのはちょっと意外です。
 
Alexey Navoykov:
元々そこに置いた型にキャストする(または dynamic_cast で確認する)。
//    (A*)Pointers[i].OnInit();
    ((A*)Pointers[i]).OnInit();

これはあくまで、ブラケットが必要か不要かというテーマで...。このキャスティングでは、実行すると上のスクリプトのようにバツになります。つまり、配列ポインタの要素が参照するクラスの名前を知っておく必要があります。

それじゃあ、何が便利なのかわからない。


MQはvoid*を一箇所しか使っていません。

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

MQはvoid*を一箇所しか使っていません。

彼らはすべてをCObjectで 構築しているため、そのクラスから継承されない独自のクラスやインターフェイスのコンテナを使用することが不可能になります。 すなわち、普遍的な解決策ではありません。

これは、彼らのライブラリが作られた当時、まだMQLにvoid*がなかったからでしょう。 一方で、彼らは、いくつかの操作(中のポインタの値を変える)に関与するオブジェクト自体も持っており、それ自体が野暮なのですが。

 
Alexey Navoykov:

このため、そのコンテナを自分のクラスやそのクラスから継承していないインターフェースに使用することは不可能であり、すなわち普遍的な解決策とはならない。

おそらく、彼らのライブラリが作られた時点では、まだMQLにvoid*が存在しなかったからだろう。

残念ながら、その使用例を見たことがないのです。

理由: