arrays - C++11 list initialization weird behaviour on Visual Studio 2013 -
i'm trying pass array function , prevent writing "std::unique_ptr" each time , make inline construction possible, introduce typedef (itemlist) alias array.
#include <iostream> #include <memory> class base { public: base() { std::cout << "base ctor" << std::endl; }; virtual ~base() { std::cout << "base dtor" << std::endl; }; }; typedef std::unique_ptr<base> itemlist[]; template<typename t> class derived : public base { t val; public: derived(t i) { val = i; std::cout << "derived ctor" << val << std::endl; }; ~derived() { std::cout << "derived dtor" << val << std::endl; }; }; void dummyfunc(itemlist) { } void testfunc() { dummyfunc(itemlist{ std::make_unique<derived<int>>(2), std::make_unique<derived<float>>(3.0f) }); } //entry point int main() { testfunc(); return 0; }
this works intended in debug build , prints;
base ctor derived ctor2 base ctor derived ctor2 derived dtor2 base dtor derived dtor2 base dtor
so far good. when build in release mode (with native compilers) get;
base ctor derived ctor2 base ctor derived ctor3 derived dtor2 base dtor
the second item in array not getting destructed upon exiting lifecycle of array. way make work expect, using c++03 style initialization or debug mode;
itemlist tmplist = { std::make_unique<derived<int>>(2), std::make_unique<derived<float>>(2.0f) }; dummyfunc(tmplist);
this results in intended behavior (all destructors called).
i have not tested other compiler yet expected behaviour? doing wrong or missing something?
update:
interestingly dtors called expected base instances;
dummyfunc(itemlist{ std::make_unique<base>(), std::make_unique<base>() });
outputs;
base ctor base ctor base dtor base dtor
and initializing array (without function call) behaves same function call.
your code not build g++ 6.2, , error explicit enough explain why don't expected behavior:
foo.cc:44:15: error: taking address of temporary array dummyfunc(itemlist{ ^~~~~~~~~ std::make_unique<derived<int>>(2), ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ std::make_unique<derived<float>>(3.0f) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ });
a simple fix use:
using itemlist = std::initializer_list<std::unique_ptr<base>>;
instead of array.
update: behavior of vs might correct one:
an lvalue or rvalue of type “array of n t” or “array of unknown bound of t” can converted prvalue of type “pointer t”. result pointer first element of array.
Comments
Post a Comment