vector<unique_ptr<Base> > 使用 Derived 的初始化列表
vector<unique_ptr<Base> > using initialization list of Derived
我有一个后续问题:
我想实现与引用问题基本相同的目标,但这次使用多态 类。也就是说,我想使用初始化列表创建一个 std::vector<std::unique_ptr<Base>>
。
#include <vector>
#include <memory>
#include <iterator>
#include <iostream>
template<class T>
struct movable_il {
mutable T t;
operator T() const&& { return std::move(t); }
movable_il( T&& in ): t(std::move(in)) {}
};
template<class T, class A=std::allocator<T>>
std::vector<T,A> vector_from_il( std::initializer_list< movable_il<T> > il ) {
std::vector<T,A> r( std::make_move_iterator(il.begin()), std::make_move_iterator(il.end()) );
return r;
}
// Example with class hierarchy
class Base
{
public:
Base(int in) : x(in) {}
virtual ~Base() = default;
virtual void print() const = 0;
protected:
int x;
};
class Derived1 : public Base
{
public:
Derived1(int in) : Base(in) {}
virtual ~Derived1() = default;
virtual void print() const override { std::cout << "Derived1: " << x << std::endl; }
};
class Derived2 : public Base
{
public:
Derived2(int in) : Base(in) {}
virtual ~Derived2() = default;
virtual void print() const override { std::cout << "Derived2: " << x << std::endl; }
};
int main()
{
{
auto v = vector_from_il< std::unique_ptr<Base> >({
std::make_unique<Derived1>(7),
std::make_unique<Derived2>(3)
});
for (const auto & val : v)
val->print();
}
return 0;
}
编译器(GCC 7.4.0 on Ubuntu 18)错误消息是:
template argument deduction/substitution failed:
cannot convert '{std::make_unique(_Args&& ...)
[with _Tp = Derived1;
_Args = {int};
typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<Derived1, std::default_delete<Derived1> >](),
std::make_unique(_Args&& ...)
[with _Tp = Derived2;
_Args = {int};
typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<Derived2, std::default_delete<Derived2> >]()}'
(type '<brace-enclosed initializer list>') to type 'std::initializer_list<movable_il<std::unique_ptr<Base> > >'
我假设这个错误与模板参数推导过程中没有考虑转换有关,所以这可能是不可能的。
添加额外的构造函数
template <typename U>
movable_il(U&& in): t(std::forward<U>(in)) {}
修复编译。
Demo.
我有一个后续问题:
我想实现与引用问题基本相同的目标,但这次使用多态 类。也就是说,我想使用初始化列表创建一个 std::vector<std::unique_ptr<Base>>
。
#include <vector>
#include <memory>
#include <iterator>
#include <iostream>
template<class T>
struct movable_il {
mutable T t;
operator T() const&& { return std::move(t); }
movable_il( T&& in ): t(std::move(in)) {}
};
template<class T, class A=std::allocator<T>>
std::vector<T,A> vector_from_il( std::initializer_list< movable_il<T> > il ) {
std::vector<T,A> r( std::make_move_iterator(il.begin()), std::make_move_iterator(il.end()) );
return r;
}
// Example with class hierarchy
class Base
{
public:
Base(int in) : x(in) {}
virtual ~Base() = default;
virtual void print() const = 0;
protected:
int x;
};
class Derived1 : public Base
{
public:
Derived1(int in) : Base(in) {}
virtual ~Derived1() = default;
virtual void print() const override { std::cout << "Derived1: " << x << std::endl; }
};
class Derived2 : public Base
{
public:
Derived2(int in) : Base(in) {}
virtual ~Derived2() = default;
virtual void print() const override { std::cout << "Derived2: " << x << std::endl; }
};
int main()
{
{
auto v = vector_from_il< std::unique_ptr<Base> >({
std::make_unique<Derived1>(7),
std::make_unique<Derived2>(3)
});
for (const auto & val : v)
val->print();
}
return 0;
}
编译器(GCC 7.4.0 on Ubuntu 18)错误消息是:
template argument deduction/substitution failed:
cannot convert '{std::make_unique(_Args&& ...)
[with _Tp = Derived1;
_Args = {int};
typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<Derived1, std::default_delete<Derived1> >](),
std::make_unique(_Args&& ...)
[with _Tp = Derived2;
_Args = {int};
typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<Derived2, std::default_delete<Derived2> >]()}'
(type '<brace-enclosed initializer list>') to type 'std::initializer_list<movable_il<std::unique_ptr<Base> > >'
我假设这个错误与模板参数推导过程中没有考虑转换有关,所以这可能是不可能的。
添加额外的构造函数
template <typename U>
movable_il(U&& in): t(std::forward<U>(in)) {}
修复编译。
Demo.