22

IBMのWebサイトで見つけたこの例を考えてみましょう。

#include <iostream>
using namespace std;

void f(double) { cout << "Function f(double)" << endl; }

template<class T> void g(T a) {
  f(123);
  h(a);
}

void f(int) { cout << "Function f(int)" << endl; }
void h(double) { cout << "Function h(double)" << endl; }

void i() {
  extern void h(int);
  g<int>(234);
}

void h(int) { cout << "Function h(int)" << endl; }

int main(void) {
    i();
}

何を印刷しますか?

  • 私がこの例を採用したIBMのドキュメントは、ここから入手でき、次のように出力されます。

    Function f(double)
    Function h(double)
    

    これの理論的根拠は、テンプレートパラメータに依存する名前ルックアップがのインスタンス化の直前に実行されるi()ため、は検出されますh(double)が、は検出されないということh(int)です。

  • GCC 4.4.1を使用してコンパイルすると、次のように出力されます。

    Function f(double)
    Function h(int)
    

    GCCは、他のすべてがコンパイルされた後、テンプレート内のテンプレートパラメータに依存する名前を検索しているように見えるため、との両方h(double)を検出h(int)し、後者を優先します。

  • Clang 2.8を使用してコンパイルすると、コンパイルに失敗します。コンパイラエラーは次のとおりです。

    ibm_example.cc:8:3: error: use of undeclared identifier 'h'
      h(a);
      ^
    ibm_example.cc:16:3: note: in instantiation of function template specialization 'g<int>' requested here
      g<int>(234);
      ^
    1 error generated.
    

    Clangは、テンプレートが宣言された時点でテンプレート内のテンプレートパラメータに依存する名前を検索しているように見えるため、どちらh(double)も検出されませんh(int)

どちらが正しいですか?

4

1 に答える 1