次のようなCRTP基本クラスがあります。
template<typename Derived, size_t DIMS>
class Base {
public:
// here is I think where the problem is
inline const Derived& self() const {return *static_cast<const Derived*>(this);}
};
次に、派生クラスは次のように定義されます
template<typename T, size_t ... Rest>
class Derived: public Base<Derived<T,Rest...>,sizeof...(Rest)> {
public:
Derived() = default;
// This constructor binds any arbitrary expression to Derived
template<typename Expr, size_t DIMS>
inline Derived(const Base<Expr,DIMS>& src_) {
const Expr &src = src_.self();
print(src.rhs);
}
};
独自の演算子を定義することを念頭に置いて、AddOperator
ベースから継承する次のものもあります
template<typename TLhs, typename TRhs, size_t DIMS>
struct AddOperator: public Base<AddOperator<TLhs, TRhs, DIMS>,DIMS> {
AddOperator(const TLhs& lhs, const TRhs& rhs) : lhs(lhs), rhs(rhs) {
print(rhs);
}
const TLhs &lhs;
const TRhs &rhs;
};
次に、型とプリミティブ型のoperator+
間のオーバーロードは、ある種のプロキシ/式のみを返します。Derived
template<typename TLhs, typename TRhs, size_t DIM0,
typename std::enable_if<!std::is_arithmetic<TLhs>::value &&
std::is_arithmetic<TRhs>::value,bool>::type = 0 >
inline AddOperator<TLhs, TRhs, DIM0>
operator+(const Base<TLhs,DIM0> &lhs, TRhs rhs) {
return AddOperator<TLhs, TRhs, DIM0>(lhs.self(), rhs);
}
ただし、これを下で呼び出すと、 of のclang
ガベージ値が取得されます。次に例を示します。rhs
AddOperator
int main() {
Derived<double,2,2> g;
Derived<double,2,2> x = g+28;
return 0;
}
lhs
とrhs
inの両方AddOperator
が型である場合の他のオーバーロードには、Derived
この問題はありません。
この問題は、 の下でのみ発生しclang
ます。gcc
コンパイルされたコードは正常に動作するようです。問題がどこにあるか誰か知っていますか?