5

これはさらに詳細なフォローアップです: この質問

次のコードを検討してください。

template <typename T>
class A {
 public:
  template <typename T2>
  const T2* DoSomething() { ... }
};

template <typename T>
class B : public A<T> {
 public:
  const int* DoSomethingElse() {
    return this->DoSomething<int>();  // Compiler wants 'template' keyword here:
 // return this->template DoSomething<int>();
  }
};

なぜこれはコンパイルされないのですか?規格の関連セクションが14.2/4であることは理解していますが、これが機能しない理由の要点を理解しているかどうかはわかりません。誰かがそのセクションの文言を分解して、これが機能しない理由を説明できますか?さらに、(一般的に)どのような状況でテンプレートキーワードを省略できるかを説明できますか?

C ++ 11では、次のコードコンパイルされることに注意してください。

template <typename T>
class A {
 public:
  template <typename T2>
  const T2* DoSomething() { ... }
};

class B {
 public:
  scoped_ptr<A<int>> var_;

  const int* DoSomethingElse() {
    return var_->DoSomething<int>();
  }
};

違いは何ですか?

4

2 に答える 2

3

これは、C++が文脈自由文法ではないためです。

通常、コンパイラは以前に宣言された記号を調べて、トークンシーケンスDoSomethingの山括弧、、、<が関係演算子であるか、テンプレート名の一部であるかを判断します。これはテンプレートであり、特殊化されるかどうかはまだ不明であるため、コンパイラーはシンボルテーブル内の以前の宣言に依存できず、プログラマーの支援が必要です。int>A<T>

于 2012-06-01T19:16:52.513 に答える
3

あなたがこれを持っているとしましょう:

template <> class A<float>
{
    int DoSomething;
    // ...
};

突然、その表現this->DoSomething < ...は非常に異なる何かを意味します。依存する名前である場合、その名前が何を意味するのかを判断する方法はありません。そのため、名前が変数、型名、テンプレートのいずれであるかを明示する必要があります。

于 2012-06-01T19:17:35.927 に答える