私はいくつかの特殊化されたベクトルテンプレートを書いているので、ベクトルの最初のいくつかの項目(x、y、z、wなど)サイズ。 KennyTM's answerはこれに大きな助けとなりました。また、演算子を自然に使用できるように、Curiously recurring template patternの形式を追加しました。ここでは、基本クラスと追加機能(簡潔にするために省略最もメンバーの実装)との専門である:CRTPとテンプレートの特殊化を伴う演算子の奇妙な振る舞い
template<int Dim, typename V, typename ItemType = float>
class VectorImpl
{
public:
typedef ItemType value_type;
VectorImpl() { elements.fill(0); }
VectorImpl(std::initializer_list<ItemType> init_list);
V operator+(const V& other)
{
V result;
for (int i = 0; i < Dim; ++i)
result.elements[i] = elements[i] + other.elements[i];
return result;
}
QString toString();
// ... other members ...
protected:
VectorImpl(const VectorImpl& other) = default;
protected:
std::array<ItemType, Dim> elements;
};
template<int Dim, typename ItemType = float>
class Vector : public VectorImpl<Dim, Vector<Dim, ItemType>, ItemType>
{
typedef VectorImpl<Dim, Vector<Dim, ItemType>, ItemType> ParentType;
public:
Vector() : ParentType() {}
Vector(const ParentType& other) : ParentType(other) {}
Vector(std::initializer_list<ItemType> init_list) : ParentType(init_list) {}
};
template<typename ItemType>
class Vector<3, ItemType> : public VectorImpl<3, Vector<3, ItemType>, ItemType>
{
typedef VectorImpl<3, Vector<3, ItemType>, ItemType> ParentType;
public:
Vector() : ParentType() {}
Vector(const ParentType& other) : ParentType(other) {}
Vector(std::initializer_list<ItemType> init_list) : ParentType(init_list) {}
ItemType x() const { return this->elements[0]; }
ItemType y() const { return this->elements[1]; }
ItemType z() const { return this->elements[2]; }
};
は、と私はqDebug()<<
サポートを追加したかったので、私はこれをしなかった:
template<int Dim, typename ItemType>
QDebug operator<<(QDebug dbg, Vector<Dim, ItemType>& v)
{
dbg.nospace() << v.toString();
return dbg.space();
}
、コードは、次のことはコンパイルし、動作します:
Vector<3> v1 = { 3,4,5 };
qDebug() << v1;
この1は、あまりにも、ありません:
Vector<3> v1 = { 3,4,5 };
Vector<3> v2 = { 1,-1,1 };
qDebug() << v1;
auto v3 = v1 + v2;
qDebug() << v3;
しかし、この1つはない:
Vector<3> v1 = { 3,4,5 };
Vector<3> v2 = { 1,-1,1 };
qDebug() << (v1 + v2);
コンパイラは言う:
error: no match for 'operator<<' in 'qDebug()() << v1.Vector<3>::.VectorImpl::operator+ [with int Dim = 3, V = Vector<3>, ItemType = float]((*(const Vector<3>*)(& v2)))'
何が起こっていますか?変数に代入するときに、v1 + v2
の型が異なるのはなぜですか?これをコンパイルするにはどうすればよいですか?
私はこの問題のように感じる(参照のconstをしていない)SOにたくさん出てきます。 –
私はそれを逃したとは信じられません...ありがとう! –
@TamásSzelei:最高のことに... :-) –