代わりにスカラーを取る別の人をオーバーロードする引数として配列をとるコンストラクタを構築しようとしています。コードは以下のとおりです。C++クラスのテンプレートコンストラクタ - 配列(U *)のオーバーロード参照(U&)が失敗しました
#include <iostream>
template <typename T>
class SmallVec { // This is a 3 dimensional vector class template
public:
T data[3] = {0}; // internal data of class
template <typename U>
explicit SmallVec(const U& scalar) { // if a scalar, copy it to each element in data
for(auto &item : data) {
item = static_cast<T>(scalar);
}
}
template <typename U>
explicit SmallVec(const U* vec) { // if a vector, copy one by one
for(auto &item : data) {
item = static_cast<T>(*vec);
vec++;
}
}
};
int main() {
float num = 1.2;
float *arr = new float[3];
arr[2] = 3.4;
SmallVec<float> vec1(num); // take num, which works fine
SmallVec<float> vec2(arr); // !!!--- error happens this line ---!!!
std::cout << vec1.data[2] << " " << vec2.data[2] << std::endl;
return 0;
}
コンパイラは
error: invalid static_cast from type 'float* const' to type 'float'
はもちろん、vec2(arr)
はまだ最初のコンストラクタを呼び出すと文句を言い。ただし、template <typename U>
を削除し、U
をT
に置き換えてください。プログラムは正常に動作します。これを修正するにはどうしたらよいですか?
何か提案がありがとうございます!
ヒント:最初のコンストラクタは両方とも呼び出されます。 – LogicStuff
@LogicStuff迅速なコメントをいただきありがとうございます。はい、最初のコンストラクタが再び呼び出されます。これはおそらく配列(または配列へのポインタ)が参照渡しされることを意味しますか?しかし、どのようにプログラムに2番目のコンストラクタを見つけるか、あるいは最初のメソッドで引数がスカラーか配列かどうかを区別する方法を教えてください。もう少しヒントをお願いしますか? – astroboylrx
あなたは[SFINAE](http://en.cppreference.com/w/cpp/language/sfinae)またはタグディスパッチを使用する必要があります。 – LogicStuff