VC6のダメなとこをまとめておく【随時更新(予定)】
いったいぜんたいどこがダメなのよって話をあまり聞かない
forがダメだとかテンプレートがダメとか
じゃあどういう風にダメなのよって調べてまとめてみた
- エラーコードが書いてあるのは対象の下の行でエラーがでるってこと
- 解決策がないのは解決法を募集あるいは無理
同じテンプレートで明示を変更するのがダメ
template <int N> void foo1(int a) { std::cout << N << ":" << a << std::endl; }; int main(int argc, char *argv[]){ foo1<1>(2); //2:2って表示されるよ!なんで? foo1<2>(2); }
これはintだけどもちろん型名でも同様
解決法
template <int N> class foo1_a { public: void operator()(int a) { std::cout << N << ":" << a << std::endl; }; }; int main(int argc, char *argv[]){ foo1_a<1>()(2); foo1_a<2>()(2); }
for
void foo2() { for(int i=0;i<5;i++) std::cout << i << std::endl; //↓C2374 for(int i=5;i<10;i++) std::cout << i << std::endl; }
解決策
どこかのヘッダに書きましょう
#define for if(0); else for
同名メンバのテンプレート
template <class T> class foo3 { public: foo3(){} //↓C2535 template <class U> foo3(){} };
クラス内static const
class foo4 { public: foo4():i(20){} //これは通る!ふしぎ! //C2258 const static int i = 20; };
テンフレート関数のPartial Ordering
template<class T> void foo5( T ) { std::cout << "foo5( T ) called." << std::endl;}; template<class T> void foo5( T* ){ std::cout << "foo5( T* ) called." << std::endl;}; template<class T> void foo5( const T* ) { std::cout << "foo5( const T* ) called." << std::endl;}; int main(int argc, char *argv[]){ foo5( a ); int *p; const int *cp; foo5( p ); //C2667,C2668 foo5( cp ); //C2667,C2668 }
covariantの戻り値の型を持つ 仮想関数
class foo7_a { public : virtual foo7_a* f( ); }; class foo7_b : public foo7_a { public : //C2555 foo7_b* f( ); };
ADLがoperator以外では動かない
namespace foo8 { struct T2 { }; void g( T2 ) { } T2 operator+( T2 a, T2 b ) { std::cout << "in T2::+" << std::endl; return b; } } int main(int argc, char *argv[]){ foo8::T2 t1, t2; // C2065 (引数型から関数を特定できない) g( t1 ); t1 + t2; }
テンプレートの部分特殊化
template<class T, int I> struct foo9 { void f(){}; }; //C2989,C2988 template<class T> struct foo9<T,2> {};
多階層テンプレート
template<class T> class foo11_ {}; //C2954,C2951,C2226,C2143,C2059 (パースできねーよバーカみたいな) template<class U, class V, template<class T> class C = foo11_> class foo11 { C<U> key; C<V> value; };
const void*を返す関数は怪しい
boostのソースより
boost/aligned_storage.hpp
// MSVC6 seems not to like inline functions with const void* returns, so we // declare the following here:
らしいけどこれ本当なんでしょうか。出典求む
関数に対するoperator==
class Foo{ const int A(){ return 1; }; const bool B(){ return A()==0; }; // const bool C(){ return A==0; }; //VC6だとコンパイル通る const bool D(){ return A<0; }; //VC6でもNG const int E() { return A=0; }; //VC6でもNG const int F() { return A+1; }; //VC6でもNG };
安直なgetterとかで
class Foo{ int value; const int Value() const; };
なんて使い方をしてる場合、()を抜くtypoをしてもVC6は教えてくれません
(2011/02/02追記)そういえば
これダメだった気がするけど今確認できない
template <unsigned char A> void func(){}
対策
#define unsigned char UCHAR template <UCHAR A> void func(){}
(2011/02/03追記)iteratorに対するポインタのキャスト
以下のソースは、VC6で通ります
std::vector<int> a(3); a.erase(&a[0]);
環境を変えるときには全部iteratorに書き直さないとダメ