私は GSL のいくつかの部分に小さな C++ ラッパーを書き、次のパズルに遭遇しました (私にとって)。コードは次のとおりです (要点のみに縮小)。
#include <stdlib.h>
struct gsl_vector_view {};
class Vector : protected gsl_vector_view {
public:
Vector ( const Vector& original );
Vector ( const gsl_vector_view view );
};
class AutoVector : public Vector {
public:
explicit AutoVector ( const size_t dims );
};
void useVector ( const Vector b ) {}
void test () {
const AutoVector ov( 2 );
useVector( ov );
}
gcc 4.4.5 g++ -c v.cpp を使用してコンパイルされませんが、生成されます
In function ‘void test()’:
19: error: call of overloaded ‘Vector(const AutoVector&)’ is ambiguous
7: note: candidates are: Vector::Vector(gsl_vector_view)
6: note: Vector::Vector(const Vector&)
19: error: initializing argument 1 of ‘void useVector(Vector)’
保護された基底クラス gsl_vector_view が useVector( Vector ) の呼び出しで考慮されていることに驚きました。useVector は、「The C++ Programming Language」、3rd e.、p. 405 であるため、その保護された情報にアクセスできないため、混乱することはありません。コンストラクターを次のように宣言することで、あいまいさを取り除くことができることを知っています
explicit Vector ( const gsl_vector_view view );
私が知らなかった (正直なところ、どちらも理解していない) ことは、コンストラクターを次のように宣言すると、オーバーロードされた呼び出しのあいまいさがなくなることです。
Vector ( const gsl_vector_view& view );
つまり、参照によって引数を渡します(とにかく、これは適切な方法だと思います)。