0

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

template<class T>
class Base {
  public:
    void doSomething(){}
};

template<class T>
class Derived : public Base<T> {
  public:
    void doMore() {
      doSomething(); //Affected line
    }
};

「影響を受ける行」とコメントされた行で、g++ (4.7) は次のように述べています。

test.cc:11:16: error: there are no arguments to ‘doSomething’ that depend on a template parameter, so a declaration of ‘doSomething’ must be available [-fpermissive]

今私は疑問に思っています:

  • テンプレート パラメータ T が存在しない場合、このエラーは発生しません。違いはなんですか?
  • g++ は明らかにこの問題を解決できます (-fpermissive を追加すると、正常にコンパイルされます)。私は、g++ が「ユーザー」 (プログラマー) としての私にとって最高のエクスペリエンスを作ろうとしていると想定しています。g++ がこのコードを受け入れない場合、私にとってどのような利点がありますか?

ありがとう!ネイサン

4

2 に答える 2

2

標準に準拠していないコードを追加しthisたりBase<T>記述したりしない場合、GCC はこれを防止したいと考えています。GCC 4.7 の変更ログ エントリも参照してください。

G++ は、テンプレートで使用される非修飾名が、テンプレートの定義の時点でスコープ内で、またはインスタンス化の時点で引数依存のルックアップによって検出された適切な宣言を持たなければならないなど、2 フェーズ ルックアップ ルールを正しく実装するようになりました。その結果、テンプレートの後または依存ベースで宣言された関数を見つけるために、インスタンス化の時点で 2 番目の非修飾ルックアップに依存するコードは拒否されます。コンパイラは、影響を受けるコードを修正する方法を提案し、-fpermissive コンパイラ フラグを使用すると、コードを警告付きでコンパイルできます。

template <class T>
void f() { g(T()); } // error, g(int) not found by argument-dependent lookup
void g(int) { } // fix by moving this declaration before the declaration of f

template <class T>
struct A: T {
  // error, B::g(B) not found by argument-dependent lookup
  void f() { g(T()); } // fix by using this->g or A::g
};

struct B { void g(B); };

int main()
{
  f<int>();
  A<B>().f();
}

(ここにあります: http://gcc.gnu.org/gcc-4.7/changes.html )。

于 2012-05-29T11:49:49.407 に答える
1

これについては、GCC VerboseDiagnosticswikiページで説明されています。

g ++がこのコードを受け入れない場合の私にとっての利点は何ですか?

これは標準に準拠し、他のコンパイラと一致しているため、コードの移植性と正確性が保証されます。

于 2012-05-29T13:06:29.237 に答える