首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >是否有一种从std::向量实例化boost::数组的优雅方法?

是否有一种从std::向量实例化boost::数组的优雅方法?
EN

Stack Overflow用户
提问于 2018-04-19 12:54:47
回答 3查看 2.5K关注 0票数 2

在编写接口时,我必须将std::vector<double>实例转换为boost::array<double,N>。每一次,通过构造(没有bug),我确信向量的大小是正确的。

下面是我目前正在做的一个例子(我有大约100个这样的函数要写在接口中):

代码语言:javascript
运行
复制
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标记,它也可能有所帮助。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-04-19 13:10:14

某物像这样

代码语言:javascript
运行
复制
#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,而在发布模式中它被消除了。

票数 5
EN

Stack Overflow用户

发布于 2018-04-19 13:08:37

编写模板函数:

代码语言:javascript
运行
复制
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;
}

然后,您的函数将成为一个行:

代码语言:javascript
运行
复制
double foo1(const std::vector<double>& x)
{
    return foo1_( convert<double,4>( x ) );
}

实例化

票数 2
EN

Stack Overflow用户

发布于 2018-04-19 13:13:42

您可以对元素的数量进行模板(这也是array<>所做的)。如果合理地对参数进行排序,则只需指定大小,并且仍然可以推导出double

代码语言:javascript
运行
复制
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;
}

会被使用

代码语言:javascript
运行
复制
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));
}

但是,一个更好的想法是重新实现foo1_foo2_的迭代器(或者类似于gsl::span)。您可以根据需要使用assert(std::distance(begin, end) == 4)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49921688

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档