Передача объекта динамического размещения в boost :: any конструктор

#include <iostream>
#include <boost/any.hpp>

class Str
{
public:
// default constructor
Str() : str_{"Hello, World!"} { std::cout << "A::A()" << this << std::endl;  }

// copy constructor
Str(const Str& that) : str_(that.str_) { std::cout << "A::A(const A&)" << this << std::endl; }
Str(Str& that) : str_(that.str_) { std::cout << "A::A(A&)" << this << std::endl; }

// move constructor
Str(const Str&& that) : str_(std::move(that.str_)) { std::cout << "A::A(const A&&)" << this << std::endl; }
Str(Str&& that) : str_(std::move(that.str_)) { std::cout << "A::A(A&&)" << this << std::endl; }
// destructor
~Str() { std::cout << "~A::A()" << this << std::endl; }

// str print method
void print() const { std::cout << str_ << '\n'; }

private:
std::string str_;
};

int main(int argc, char *argv[])
{
auto* str = new Str;
boost::any a(*str);
if (a.empty()) {
std::cout << "empty\n";
} else {
std::cout << "not empty\n";
}
auto s = boost::any_cast<Str>(&a);
std::cout << s << std::endl;
std::cout << a.empty() << std::endl;
delete str;
return 0;
}

Эта простая программа имеет вывод:

A::A()0x24f5c20
not empty
0
0
~A::A()0x24f5c20

Итак, чтобы понять это правильно, правильный вывод программы должен быть:

A::A()0x24f5c20
A::A(const A&)some address // copy str before passing into any constructor
not empty
some address
0
~A::A()some address //~any() call ~A()some address
~A::A()0x24f5c20

Похоже, не понимаю, что происходит.
Это было скомпилировано с g ++ версии 5.4.0.
Люди! Что со мной не так? знак равно

1

Решение

Я предполагаю, что вы используете старую версию программы или неправильно ее перестраиваете. (Я тестировал с надстройкой 1.62, а также 1.64. Используя Gcc 5.4 и Clang.)

Программа имеет ожидаемый эффект и не вызывает какого-либо неопределенного поведения.

Обратите внимание, что нет причин использовать new/delete там и str не используется после инициализации boost::any, поскольку boost::any хранит значения — никогда не ссылки. Поэтому вы могли бы просто сказать

auto *str = new Str;
boost::any a(*str);
delete str;

Или просто

Str str;
boost::any a(str);

Или даже

boost::any a(Str{}); // beware of "most vexing parse"

Вы можете сравнить вещи Жить на Колиру

0

Другие решения

Других решений пока нет …