为什么 boost::multi_array 的 ConstMultiArrayConcept 有一个 NumDims 模板参数?

问题描述 投票:0回答:2

我编写了一个处理

operator<<
boost::multi_array
专业化,并使用
ConstMultiArrayConcept
,以便它可以在外部数组和子数组上工作。不过,我想知道为什么
multi_array
概念有一个
std::size_t NumDims
模板参数,因为它可以简单地从
multi_array
中提取。
NumDims
ConstMultiArrayConcept
的唯一用途是作为
idgen_helper
的递归深度参数,用于测试切片。

作为参考,以下是

multi_array
概念的标题: http://www.boost.org/doc/libs/1_51_0/boost/multi_array/concept_checks.hpp

这是我超载的

operator<<

template <typename CharT, typename Traits, typename MultiArrayT>
BOOST_CONCEPT_REQUIRES(
                       ((boost::multi_array_concepts::ConstMultiArrayConcept<MultiArrayT, MultiArrayT::dimensionality>)),
                       (std::basic_ostream<CharT, Traits>&)) // return type
operator <<( std::basic_ostream<CharT, Traits>& os, MultiArrayT const& ary )
{
    typename std::basic_ostream<CharT, Traits>::sentry opfx( os );

    if ( opfx ) {
        boost::multi_array_types::size_type const* sizes = ary.shape();
        // using Mathematica array notation
        os << "{";
        for ( int i = 0; i < sizes[0]; ++i ) {
            if ( i > 0 ) os << ", ";
            // verbose just to keep the types apparent
            typedef typename MultiArrayT::const_reference subType;
            subType item = ary[i];
            os << item;
        }
        os << "}\n";
    }
    return os;
}

这个专业化是有效的,但我的理解中肯定缺少一些东西。任何线索将不胜感激。

c++ boost boost-multi-array c++-concepts
2个回答
2
投票

概念模板类声明:

template <typename Array, std::size_t NumDims>  struct ConstMultiArrayConcept
{
...
};

查看

ConstMultiArrayConcept
在 Boost 代码中实际如何使用:

 template <typename T, std::size_t NumDims>
 class multi_array_ref {
   ...
   // Assignment from other ConstMultiArray types.
   template <typename ConstMultiArray>
   multi_array_ref& operator=(const ConstMultiArray& other)
   {
      function_requires< 
         detail::multi_array::
         ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
      ...

multi_array_view& operator=()
sub_array& operator=()
中的代码相同,采用其他
ConstMultiArray
类型。

看起来像

NumDims
不是传递数组类型Array
的维数,它是外部数组类型的维数,用于检查与给定其他数组类型的赋值兼容性。所以无法从 
Array
 模板参数推导出来。


0
投票

ConstMultiArrayConcept<MA, D>

MutableMultiArrayConcept<MA, D>
 检查 
MA
 是否满足维度为 
D
 的(可变)数组的概念。

例如,这些概念检查是否成功:

using MA = boost::multi_array<int, 1>; BOOST_CONCEPT_ASSERT((boost::multi_array_concepts::ConstMultiArrayConcept<MA, 1>)); BOOST_CONCEPT_ASSERT((boost::multi_array_concepts::MutableMultiArrayConcept<MA, 1>));
因为 

MA

 的维度为 1。

相同

{ using MA = boost::multi_array<int, 2>; BOOST_CONCEPT_ASSERT((boost::multi_array_concepts::ConstMultiArrayConcept<MA, 2>)); BOOST_CONCEPT_ASSERT((boost::multi_array_concepts::MutableMultiArrayConcept<MA, 2>)); }
然而,这个失败了,因为存在维度不匹配:

{ using BMA = boost::multi_array<int, 2>; BOOST_CONCEPT_ASSERT((boost::multi_array_concepts::ConstMultiArrayConcept<MA, 1>)); BOOST_CONCEPT_ASSERT((boost::multi_array_concepts::MutableMultiArrayConcept<MA, 1>));
出现错误消息:

/usr/include/boost/multi_array/concept_checks.hpp: In instantiation of ‘static void boost::multi_array_concepts::detail::idgen_helper<0>::call(Array&, const IdxGen&, Call_Type) [with Array = boost::multi_array<int, 2>; IdxGen = boost::detail::multi_array::index_gen<1, 1>; Call_Type = long int]’: /usr/include/boost/multi_array/concept_checks.hpp:71:44: required from ‘void boost::multi_array_concepts::ConstMultiArrayConcept<Array, NumDims>::constraints() [with Array = boost::multi_array<int, 2>; long unsigned int NumDims = 1]’ /usr/include/boost/concept/detail/has_constraints.hpp:32:62: required by substitution of ‘template<class Model> boost::concepts::detail::yes boost::concepts::detail::has_constraints_(Model*, boost::concepts::detail::wrap_constraints<Model, (& Model::constraints)>*) [with Model = boost::multi_array_concepts::ConstMultiArrayConcept<boost::multi_array<int, 2>, 1>]’ /usr/include/boost/concept/detail/has_constraints.hpp:42:5: required from ‘const bool boost::concepts::not_satisfied<boost::multi_array_concepts::ConstMultiArrayConcept<boost::multi_array<int, 2>, 1> >::value’ /usr/include/boost/concept/detail/has_constraints.hpp:45:51: required from ‘struct boost::concepts::not_satisfied<boost::multi_array_concepts::ConstMultiArrayConcept<boost::multi_array<int, 2>, 1> >’ /usr/include/boost/concept/detail/general.hpp:51:8: required from ‘struct boost::concepts::requirement_<void (*)(boost::multi_array_concepts::ConstMultiArrayConcept<boost::multi_array<int, 2>, 1>)>’ /home/user/boost-multi/test/boost_array_concept.cpp:19:2: required from here /usr/include/boost/multi_array/concept_checks.hpp:51:8: error: no match for ‘operator[]’ (operand types are ‘boost::multi_array<int, 2>’ and ‘const boost::detail::multi_array::index_gen<1, 1>’) 51 | a[ idgen ]; | ~^ In file included from /usr/include/boost/multi_array.hpp:34, from /home/user/boost-multi/test/boost_array_concept.cpp:8: /usr/include/boost/multi_array/multi_array_ref.hpp:530:3: note: candidate: ‘template<int NDims> typename boost::multi_array_ref<T, NumDims>::array_view<NDims>::type boost::multi_array_ref<T, NumDims>::operator[](const boost::detail::multi_array::index_gen<NumDims, NDims>&) [with int NDims = NDims; T = int; long unsigned int NumDims = 2]’ 530 | operator[](const detail::multi_array::
    
© www.soinside.com 2019 - 2024. All rights reserved.