У меня есть 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);
}
Однако, когда я называю это под clang
я получаю значение мусора для rhs
из AddOperator
. Вот пример:
int main() {
Derived<double,2,2> g;
Derived<double,2,2> x = g+28;
return 0;
}
Другие перегрузках, когда оба lhs
и rhs
в AddOperator
имеют тип Derived
не имеют этой проблемы.
Эта проблема возникает только при clang
. gcc
скомпилированный код, похоже, работает нормально. Кто-нибудь знает, где проблема?
Я сам это заметил, как только отправил вопрос. благодаря –