簡體   English   中英

有沒有一種優雅的方法來從std :: vector實例化boost :: array?

[英]Is there an elegant way to instantiate a boost::array from a std::vector?

編寫接口時,我必須將std::vector<double>實例轉換為boost::array<double,N> 每次,通過構造(沒有bug),我確定矢量具有正確的大小。

這是我正在做的事情的一個例子(我在接口中有大約100個這樣的函數):

double foo1(const std::vector<double>& x)
{
  assert(x.size() == 4);
  boost::array<double,4> x_;
  for(std::size_t i = 0; i < 4; ++i)
    x_[i] = x[i];
  return foo1_(x_);
}

double foo2(const std::vector<double>& x)
{
  assert(x.size() == 6);
  boost::array<double,6> x_;
  for(std::size_t i = 0; i < 6; ++i)
    x_[i] = x[i];
  return foo2_(x_);
}

有沒有更短的方法呢?

注1:出於兼容性原因,我不使用C ++ 11。

注2:我添加了標簽stdarray因為即使它是C ++ 11標簽也可以提供幫助。

像這樣的東西:

#include <boost/array.hpp>
#include <vector>
#include <boost/range/algorithm.hpp>
#include <iostream>
#include <cassert>

template<size_t Size, class Container>
boost::array<typename Container::value_type, Size> as_array(const Container &cont)
{
    assert(cont.size() == Size);
    boost::array<typename Container::value_type, Size> result;
    boost::range::copy(cont, result.begin());
    return result;
}

int main()
{
    // this is C++11 initialization, but the rest of code is C++03-complient
    std::vector<int> v{1, 2, 3};
    boost::array<int, 3> a = as_array<3>(v);
    boost::range::copy(a, std::ostream_iterator<int>(std::cout,", "));
}

但請記住,從運行時到編譯時容器的這種“轉換”可能非常危險,因為它的正確性依賴於assert ,這在發布模式中被消除。

寫一個模板函數:

template<class T,size_t N>
std::array<T,N> convert( const std::vector<T> & v )
{
    //assert(v.size() == N);
    std::array<T,N> r;
    std::copy( v.begin(), v.end(), r.begin() );
    return r;
}

那么你的功能將成為一個襯里:

double foo1(const std::vector<double>& x)
{
    return foo1_( convert<double,4>( x ) );
}

實例

你可以模擬元素的數量(這就是array<>正在做的事情)。 如果你明智地訂購參數,你可以只指定尺寸並且仍然可以推導出double

template<std::size_t N, typename T>
boost::array<T, N> from_vector(const std::vector<T> & vec)
{
    assert(x.size() == N);
    boost::array<T, N> res;
    std::copy(vec.begin(), vec.end(), res.begin());
    return res;
}

哪個被使用了

double foo1(const std::vector<double> & vec)
{
    return foo1_(from_vector<4>(vec));
}

double foo2(const std::vector<double> & vec)
{
    return foo2_(from_vector<6>(vec));
}

但更好的想法是在迭代器(或類似gsl::span )方面重新實現foo1_foo2_ 您可以根據需要assert(std::distance(begin, end) == 4)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM