向量从一种类型到另一种c ++的隐式转换
Posted
技术标签:
【中文标题】向量从一种类型到另一种c ++的隐式转换【英文标题】:implicit conversion of vector from one type to another c++ 【发布时间】:2015-05-28 13:46:03 【问题描述】:是否可以隐式将一种类型的向量转换为另一种类型?
即让这段代码工作的某种方法(显然这是我正在尝试做的一个简化问题)
std::vector<int> intVec;
intVec.push_back(1);
std::vector<double> doubleVec = intVec;
std::vector<double> doubleVec2;
doubleVec2 = intVec;
【问题讨论】:
【参考方案1】:不,不同向量类型之间没有转换(隐式或其他)。
你可以从一个迭代器范围初始化它:
std::vector<double> doubleVec(intVec.begin(), intVec.end());
也许将其包装在一个函数中:
template <typename To, typename From>
To container_cast(From && from)
using std::begin; using std::end; // Koenig lookup enabled
return To(begin(from), end(from));
auto doubleVec = container_cast<std::vector<double>>(intVec);
【讨论】:
谢谢,但这对我不起作用。基本上我有一个类型为vectormyClass
可以从pair<int, int>
构造,这将起作用。如果不是,那么......好吧,我不知道你会如何期望任何工作。
@death_relic0:如果从pair
到myClass
的转换是隐式的,那么这将起作用。范围构造函数将隐式转换每个元素。
我 Koenig'd 你的迭代器,只是因为。需要考虑的一件事是,如果 from
是一个右值,我们是否应该有条件地使用移动迭代器在移动为 noexcept 的情况下从每个元素中提取内容?
@Yakk:如果我们正在编写一个试图涵盖所有可以想象的用例的超通用库,可能。如果我们正在为 OP 的用例编写一个简单的帮助程序,可能不会。【参考方案2】:
template<class T, class A=std::allocator<T>>
struct magic_vector:std::vector<T,A>
using base=std::vector<T,A>;
using base::base;
magic_vector(magic_vector const&)=default;
magic_vector(magic_vector &&)=default;
magic_vector& operator=(magic_vector const&)=default;
magic_vector& operator=(magic_vector &&)=default;
magic_vector()=default;
template<class U, class B,
class=typename std::enable_if<std::is_convertible<U,T>::value>::type
>
magic_vector( magic_vector<U,B> const& o ):
base( o.begin(), o.end() )
template<class U, class B,
class=typename std::enable_if<
std::is_convertible<U,T>::value
&& noexcept( T(std::declval<U&&>()) )
>::type
>
magic_vector( magic_vector<U,B>&& o ):
base(
std::make_move_iterator(o.begin()),
std::make_move_iterator(o.end())
)
;
magic_vector
s 是从其他magic_vector
s 自动转换的向量。
如果您有一个指向 magic_vector
的指针,您将其转换为指向 vector
的指针,然后将其作为 vector
删除,则结果是未定义的行为。 (但在实践中,我检查过的每个 C++ 实现都不会造成伤害)。然而,这是一种奇怪的处理vector
s 的方式。
将vector
的使用替换为magic_vector
。只要您的代码中容器的确切类型没有专门化,它就应该是一个直接替代品,除非现在它会在它们之间自动转换。
可以让magic_vector
s 自动转换为vector
s 而不仅仅是magic_vector
s。
【讨论】:
【参考方案3】:一种方法是创建转换函数。它允许您在呼叫站点表达意图:
#include <iostream>
#include <vector>
template<class To, class From, class Allocator>
std::vector<To, typename Allocator::template rebind<To>::other>
implicit_convert(const std::vector<From, Allocator>& vf)
return std::begin(vf), std::end(vf) ;
template<class To, class ToA, class From, class FromA>
void implicit_overwrite(std::vector<To, ToA>& to, const std::vector<From, FromA>& from)
to.clear();
std::copy(begin(from), end(from), back_inserter(to));
int main(int argc, const char * argv[])
using namespace std;
std::vector<int> vi 1, 2 , 3 ;
auto vd = implicit_convert<double>(vi);
cout << "after conversion\n";
for (const auto& i : vd)
cout << i << endl;
vi.push_back(4);
implicit_overwrite(vd, vi);
cout << "after copy\n";
for (const auto& i : vd)
cout << i << endl;
return 0;
预期输出:
after conversion
1
2
3
after copy
1
2
3
4
【讨论】:
【参考方案4】:你可以这样做(假设 myclass 是你的类,可以从 std::pair
构造):
#include <iostream>
#include <vector>
#include <utility>
using std::cout;
using std::endl;
class myclass
public:
myclass(const std::pair<int, int>& p): first_(p.first), second_(p.second)
int first() return first_;
int second() return second_;
private:
int first_;
int second_;
;
template <class T>
class myvector : public std::vector<T>
using base = std::vector<T>;
using base::base;
;
template<>
class myvector<myclass> : public std::vector<myclass>
public:
myvector(const std::vector<std::pair<int, int>>& vp):
std::vector<myclass>(vp.begin(), vp.end())
;
int main()
std::vector<std::pair<int, int>> vp 12,3, 1, 7;
myvector<myclass> mm = vp;
cout<<mm[0].first(); //prints 12
您从std::vector
继承myvector
,然后将其专门用于myclass
。或者,您可以在命名空间中定义 myvector
并将其访问为 mynamespace::vector<myclass>
【讨论】:
以上是关于向量从一种类型到另一种c ++的隐式转换的主要内容,如果未能解决你的问题,请参考以下文章