メモの日々


2014年01月20日(月) [長年日記]

[c++] 依存名に修飾された型名は推論されない

大した話ではないけれど分かっていなかったのでメモ。

C++のテンプレート引数の推論は、A<T>::B のような依存名に修飾された型名(言葉の使い方がこれで正しいかよく分からない)に対しては行われないみたい。C++テンプレート完全ガイドの「11.2 文脈の推論」に

だが、文脈が推論されない構造もいくつかある。

  • 修飾された型名。例えば、Q<T>::X のような型名はテンプレートパラメータ T を推論するのに使われることはない。

とあるのが該当しそう。

これにより次のコードはコンパイルエラーになる。

#include <iostream>

template<typename T>
struct A {
  struct B {
    T t;
  };
};

template<typename T>
T f(const typename A<T>::B& b) { return b.t; }

int main() {
  A<int>::B b;
  std::cout << f<int>(b) << std::endl;  // OK
  std::cout << f(b) << std::endl;       // エラー
}

g++ 4.4.7が出力するエラーメッセージは次の通り。

sample.cpp: In function ‘int main()’:
sample.cpp:16: error: no matching function for call to ‘f(A<int>::B&)’