c++ - Is it possible to make `=` prefer assignment-from-conversion over (deleted) copy-assignment? -
i've found few threads heavily imply can't done, none use same combination of operators , conditions, i'd ask more specifically. means it's quick , easy answer someone... 1 way or another!
consider example proxy class, made manage value within larger block of storage - in oversimplified representative example:
class someproxything { std::uint32_t storage; public: operator std::uint16_t() const { return storage & 0x0000ffff; } someproxything &operator=(std::uint16_t const value) { storage &= 0xffff0000; storage |= value; } };
i want all assignments work via user-defined operator
s. user should able pass in or out 'exposed' type, in case std::uint16_t
. might using various proxy class types , want apply of them. ideally, combination of types, type someproxy = anotherproxy
, let compiler rest.
but when left- , right-hand-side of assignment have same or inheritance-related types, default copy assignment operator - of course - conflicts goal. copies entire storage
, clobbering other half of uint32_t
- rather copying 'exposed' value desired. , rightly so! cases. i'd way 'assign conversion' if lhs , rhs types same. avoid this, can:
- redefine copy assignment operator perform 'proxied' copy using user-defined
operator
s - i've been doing, seems kinda hacky and, user-defined constructor/assignment operator, breaks trivially copyable status ofstruct
- need keep. stillmemcpy()
s anyway ing++
, want defined behaviour. - or
= delete
copy-assignment operator (which can tc types). assignments still try use , throw compile error - sincedelete
means 'abort error if i'm chosen overload', not 'exclude me overload resolution'. around this, must explicitly tell compiler use conversion operator , assign result:
someproxything a, b; = 42; b = static_cast<std::uint16_t>(a); // a.k.a. b.operator=( a.operator std::uint16_t() );
there doesn't seem way tell compiler 'ignore error generated preferred overload , pick next best one'. there? more generally, there way/hack/horrifying kludge, in such situation, force compiler automatically use/prefer operator
s?
in other words, ideally, in
someproxything a, b; = 42; b = a;
that b = a;
this:
b = static_cast<std::uint16_t>(a); // a.k.a. b.operator=( a.operator std::uint16_t() );
without me having type manually, use static_cast
, or implement named get/set methods. ideally, want reads/writes such proxy reads/writes basic types in written code, using =
.
i suspect that's not possible... confirmation nice!
you can this:
#include <stdint.h> #include <iostream> #include <type_traits> using namespace std; class proxy_state { protected: uint32_t storage; public: // access bytes }; static_assert( is_trivially_copyable<proxy_state>::value, "!" ); class some_proxy_thing : public proxy_state { private: public: operator std::uint16_t() const { return storage & 0x0000ffff; } auto operator=( uint16_t const value ) -> some_proxy_thing& { clog << "=(uint16_t)" << endl; storage &= 0xffff0000; storage |= value; return *this; } auto operator=( some_proxy_thing const& value ) -> some_proxy_thing& { return operator=( static_cast<uint16_t>( value ) ); } }; static_assert( not is_trivially_copyable<some_proxy_thing>::value, "!" ); auto main() -> int { some_proxy_thing a{}; some_proxy_thing b{}; const some_proxy_thing c = b; = c; = 123; = b; }
here 3 assignments output (to standard error stream) =(uint16t)
.
Comments
Post a Comment