I am using a CRTP template and trying to determine the operators that apply to its implementations. I discovered the strange behavior of uninitialized objects.
CRTP base class:
template < class C > struct CRTP { using self_t = C; const self_t& self() const { return static_cast<const self_t&>(*this); } self_t& self() { const CRTP& cs = static_cast<const CRTP&>(*this); return const_cast<self_t&>(cs.self()); } void printValue() { cout << "CRTP value : " << self().getValue() << endl; } };
Implementation 1:
struct Impl : public CRTP<Impl> { Impl() = default; Impl(Impl&&) = default; Impl(const Impl&) = default; explicit Impl(int i) : v(i) { } friend void swap(Impl& l, Impl& r) { using std::swap; swap(lv, rv); } Impl& operator=(Impl o) { swap(*this, o); return *this; } int getValue() const { return v; } private: int v; };
Implementation 2:
template < class Arg > struct Neg : public CRTP< Neg<Arg> > { Neg() = default; Neg(Neg&&) = default; Neg(const Neg&) = default; explicit Neg(Arg arg) : a(arg) { } friend void swap(Neg& l, Neg& r) { using std::swap; swap(la, ra); } Neg& operator=(Neg o) { swap(*this, o); return *this; } int getValue() const { return -a.getValue(); } private: Arg a; };
Operators ( operator! Work fine, operator~ shows the problem):
template < class C > Neg<C> operator~(CRTP<C> v) { return Neg<C>(std::move(v.self())); } template < class C > Neg<C> operator-(const CRTP<C>& v) { return Neg<C>(v.self()); } template < class C > Neg<C> operator-(CRTP<C>&& v) { return Neg<C>(std::move(v.self())); }
Now with a simple basic:
int main(void) { auto n = -Impl(10); n.printValue(); n = ~Impl(20); n.printValue(); }
Compiled with gcc, I:
CRTP value : -10 CRTP value : 0
Compiled with CLANG I get:
CRTP value : -10 CRTP value : -1186799704
Now I have 2 questions:
- Is this a standard of behavior? This happens even if I delete the default Constructors.
- How to implement operators in a "passed by value style"? I have n-ary operators that I want to implement using variadic templates, and I cannot list each combination of lvalue and rvalue links.
source share