Boost logo

Boost :

From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2023-09-30 06:26:01


On Fri, Sep 29, 2023, 23:41 Bhuyan, Jyotideep via Boost <
boost_at_[hidden]> wrote:

> Hi,
>
> I was using VS2019, boost v1.78, and C++14 version and the below code was
> working well. Same code gives build error with VS2022, boost v1.82, and
> C++17 due to "o << *boost::any_cast<T>(&a);
> " Instruction. I wanted to know why it behaves differently.
>
> Code :
>
> class any_out
> {
> struct streamer
> {
> virtual void print(std::ostream& o, const boost::any& a) = 0;
> virtual streamer* clone() = 0;
> virtual ~streamer() {}
> };
>
> public:
> any_out() : m_streamer(nullptr)
> {
> }
>
> ~any_out()
> {
> delete m_streamer;
> }
>
> template <typename T> any_out(const T& value)
> : m_streamer(new streamer_imp<T>), m_object(value)
> {
> }
>
> any_out(const any_out& a)
> : m_streamer(a.m_streamer ? a.m_streamer->clone() : nullptr),
> m_object(a.m_object)
> {
> }
>
> template <typename T> any_out& operator=(const T& r)
> {
> any_out(r).swap(*this);
> return *this;
> }
>
> any_out& operator=(const any_out& r)
> {
> any_out(r).swap(*this);
> return *this;
> }
>
> any_out& swap(any_out& r) noexcept
> {
> std::swap(m_streamer, r.m_streamer);
> std::swap(m_object, r.m_object);
> return *this;
> }
>
> friend std::ostream& operator<<(std::ostream& o, const any_out& a)
> {
> if(a.m_streamer)
> {
> a.m_streamer->print(o, a.m_object);
> }
> return o;
> }
>
> boost::any& get() { return m_object; }
> const boost::any get()const { return m_object; }
> bool empty() const { return m_object.empty(); }
>
> private:
>
> template <typename T> struct streamer_imp : public streamer
> {
> virtual void print(std::ostream& o, const boost::any& a)
> {
> try {
> if (a.empty()) {
> o << "<empty>";
> }
> else {
> o << *boost::any_cast<T>(&a);
> }
>
> }
> }
> virtual streamer* clone()
> {
> return new streamer_imp<T>();
> }
> };
>
> // Members
> streamer* m_streamer;
> boost::any m_object;
>
> };
>
>
> I have migrated to VS2022, boost v1.82, and C++17, and due to a build
> error, I have changed the code below.
>
> virtual void print(std::ostream& o, const boost::any& a)
> {
> try {
> if (a.empty()) {
> o << "<empty>";
> }
> else {
> o << boost::any_cast<T*>(a);
> }
>
> }
> }
>
>
>
> any_out anyTest;
> anyTest = 100;
> std::string actualStr;
> actualStr = make_string() << anyTest;
>
> actualStr prints nullptr (0000000) instated of value 100 for VS2022, boost
> v1.82 and C++17
>

It looks like you are using boost::any incorrectly. You cannot know ahead
of time that an any is golding a T. If you want to use a T, you have to
check it. An any my be non-empty, but may be storing some other type U.
any_cast allows you to chech it. If it retuns a null pointer, it means you
are storing some other type than T.

Maybe you need boost:optional<T> rather than boost::any?

Regards,
&rzej;

>
>
>
>
> Best Regards,
> Jyotideep (JD)
>
>
> Please be advised that this email may contain confidential information. If
> you are not the intended recipient, please notify us by email by replying
> to the sender and delete this message. The sender disclaims that the
> content of this email constitutes an offer to enter into, or the acceptance
> of, any agreement; provided that the foregoing does not invalidate the
> binding effect of any digital or other electronic reproduction of a manual
> signature that is included in any attachment.
>
> Confidential - Company Proprietary
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk