向量从一种类型到另一种类型的隐式转换

时间:2015-05-28 13:46:03

标签: c++ c++11 visual-c++

嘿,伙计们希望你能帮助我。

我想知道是否可以将一种类型的矢量转换为另一种隐式

即某种使这段代码有效的方法(显然这是我想要做的简化问题)

std::vector<int> intVec;
intVec.push_back(1);

std::vector<double> doubleVec = intVec;
std::vector<double> doubleVec2;
doubleVec2 = intVec;

4 个答案:

答案 0 :(得分:10)

不,不同的矢量类型之间没有转换(隐式或其他)。

您可以从迭代器范围初始化它:

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);

答案 1 :(得分:2)

一种方法是创建转换函数。它允许您在呼叫站点表达意图:

#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

答案 2 :(得分: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是从其他magic_vector自动转换的向量。

如果您有一个指向magic_vector的指针,并将其转换为指向vector的指针,则将其删除为vector,结果为未定义的行为。 (但实际上,我检查的每个C ++实现都没有任何损害)。然而,这是一种与vector s一起行动的奇怪方式。

vector替换为magic_vector。只要您没有对代码中容器的确切类型进行专业化,它就应该是替代品,除非它现在将在它们之间自动转换。

可以通过magic_vector进行vector自动转换,而不仅仅使用magic_vector进行自我转换。

答案 3 :(得分:1)

你可以选择这样的东西(假设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

}

您从myvector继承std::vector,然后将其专门用于myclass。或者,您可以在命名空间中定义myvector并将其作为mynamespace::vector<myclass>

进行访问