テンプレート基底クラスのエラーを修正2017年04月21日 13時41分32秒

C++ でテンプレートクラスを次の様に基底クラスにするとエラーがでる。
% cat template_base_class.cpp
#include <list>

template<typename T> class Vector : public std::vector<T>
{
public:
  int At(int i)
  {
    return at(i);
  }
};

gcc だと、 error: there are no arguments to `at' that depend on a template parameter, so a declaration of `at' must be available の様なエラーがでて、-fpermissive を渡すと、無視させて進めることが出来る。

llvm だと

template_base_class.cpp:8:14: error: use of undeclared identifier 'at'
      return at(i);
等となる。

なお、Solaris と AIX のコンパイラは大丈夫なようだ。

C++ もテンプレートなどが発展して、名前解決の規則が厳しくなり、しっかりと分かりやすくテンプレート基底クラスから、at が使われると明示してやる必要がある。

修正の仕方は三つ。

  1. this->at(i) として、メンバ関数を呼び出していると明示する。
  2. std::vector<T>::at(i) として、基底クラスから呼び出しているのを明示する。
  3. using std::vector<T>::at(i) をいれて、at は vector クラスのメンバ関数と明示する。
後の二つの方法だと、仮想関数を呼び出したい時には、基底クラスを呼び出すとしている為、うまく動作しない。今回は、std::vector を基底クラスにしたので、at 関数に virtual を付けて仮想関数にすることは出来ないので問題はないが。そこらも踏まえて修正するのであれば、this を用いた方法が最適だろう。

C++ bitset は使えない2011年01月19日 12時00分48秒

C++ の bitset が使えないと言われる理由はテンプレートクラスだからの様だ。定数を取るテンプレートの為、宣言時に大きさが固定されてしまう。

丁度ビットマップが使いたくなったので、ポインタ型で使って動的に大きさを決めようと思った。

いざ、使おうとすると大きさが固定になるので、動的には決められない。しかし、利用箇所によって大きさがまちまちで、大きく異なるので簡単には決め打ちできないのだ。

提供する関数自体は便利そうだと思ってはいたが、実際に使おうとすると思ったようにオブジェクトを生成できなかった。

同じテンプレートクラスを二度基底クラスにしてみる2010年06月06日 11時41分19秒

今回もまた、同じクラスを基底クラスとして二回指定してみる。すこし違うところはテンプレートクラスだと言うこと。今回のはコンパイルは通るはずだ。


% cat b.cpp 
template
class A
{
};

class B: public A<1>, public A<2>
{
};

int main()
{
}
sun% CC b.cpp
sun%
frebsd% g++ b.cpp
freebsd%
ibm% xlC_r a.cpp
ibm%
hp% aCC a.cpp
hp%

全てのプラットフォームで成功。

前回