向量从一种类型到另一种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);

【讨论】:

谢谢,但这对我不起作用。基本上我有一个类型为vector>的巨大代码,现在我不想使用vector>,而是想使用vector。我知道如何将pair隐式转换为myClass,但是当它们在向量中时会变得很棘手。 @death_relic0 如果myClass 可以从pair&lt;int, int&gt; 构造,这将起作用。如果不是,那么......好吧,我不知道你会如何期望任何工作。 @death_relic0:如果从pairmyClass 的转换是隐式的,那么这将起作用。范围构造函数将隐式转换每个元素。 我 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_vectors 是从其他magic_vectors 自动转换的向量。

如果您有一个指向 magic_vector 的指针,您将其转换为指向 vector 的指针,然后将其作为 vector 删除,则结果是未定义的行为。 (但在实践中,我检查过的每个 C++ 实现都不会造成伤害)。然而,这是一种奇怪的处理vectors 的方式。

vector 的使用替换为magic_vector。只要您的代码中容器的确切类型没有专门化,它就应该是一个直接替代品,除非现在它会在它们之间自动转换。

可以让magic_vectors 自动转换为vectors 而不仅仅是magic_vectors。

【讨论】:

【参考方案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&lt;myclass&gt;

【讨论】:

以上是关于向量从一种类型到另一种c ++的隐式转换的主要内容,如果未能解决你的问题,请参考以下文章

不可不会的scala隐式转换

Scala语法基础之隐式转换

Scala中的隐式转换|理解

在 .NET 中使用隐式转换替代多重继承

C的隐式类型转换

抑制从 void ** 到另一个 ** 的隐式类型转换的警告的方法?