адаптер итератора для итерации просто значений в карте?

Я предполагаю, что, например, в строке, содержащей SecondNameC , в остальных столбцах должны отображаться те же значения, что и для MainNameC , т.е. 03 и subA 123.0 g/L.

Сценарий ниже выполняет свою работу:



  

  
    
      Rep
      
        
            
                
              
            
            
              
                
                    
                  
NameIDComposition
+   

Рабочий пример см. В http://xsltransform.net/asnmyT

. что элемент контекста изменен, например в цикле for-each.

Также обратите внимание, что я изменил шаблон displaySN . Он содержит параметр MN, относящийся к элементу «main» (PPP).

Также есть некоторые изменения в шаблоне displayCompositionEN .

Я также добавил элемент xsl:output с атрибутами doctype-public и doctype-system для генерации вывода XHTML, чтобы получить представление HTML в тестовом сайте xsltransform . Но если вам это не нужно, просто удалите его.

17
задан philsquared 3 November 2008 в 16:48
поделиться

2 ответа

Я не думаю, что существует что-либо из поля. Можно использовать повышение:: make_transform.

template<typename T1, typename T2> T2& take_second(const std::pair<T1, T2> &a_pair) 
{
  return a_pair.second;
}

void run_map_value()
{
  map<int,string> a_map;
  a_map[0] = "zero";
  a_map[1] = "one";
  a_map[2] = "two";
  copy( boost::make_transform_iterator(a_map.begin(), take_second<int, string>),
    boost::make_transform_iterator(a_map.end(), take_second<int, string>),
    ostream_iterator<string>(cout, "\n")
    );
}
14
ответ дан 30 November 2019 в 10:31
поделиться

Продолжая ответ Дэвида, есть еще одна возможность поставить кипение, создав производный класс от boost :: transform_iterator. Я использую это решение в своих проектах:

namespace detail
{

template<bool IsConst, bool IsVolatile, typename T>
struct add_cv_if_c
{
    typedef T type;
};
template<typename T>
struct add_cv_if_c<true, false, T>
{
    typedef const T type;
};
template<typename T>
struct add_cv_if_c<false, true, T>
{
    typedef volatile T type;
};
template<typename T>
struct add_cv_if_c<true, true, T>
{
    typedef const volatile T type;
};

template<typename TestConst, typename TestVolatile, typename T>
struct add_cv_if: public add_cv_if_c<TestConst::value, TestVolatile::value, T>
{};

}   // namespace detail


/** An unary function that accesses the member of class T specified in the MemberPtr template parameter.

    The cv-qualification of T is preserved for MemberType
 */
template<typename T, typename MemberType, MemberType T::*MemberPtr>
struct access_member_f
{
    // preserve cv-qualification of T for T::second_type
    typedef typename detail::add_cv_if<
        std::tr1::is_const<T>, 
        std::tr1::is_volatile<T>, 
        MemberType
    >::type& result_type;

    result_type operator ()(T& t) const
    {
        return t.*MemberPtr;
    }
};

/** @short  An iterator adaptor accessing the member called 'second' of the class the 
    iterator is pointing to.
 */
template<typename Iterator>
class accessing_second_iterator: public 
    boost::transform_iterator<
        access_member_f<
            // note: we use the Iterator's reference because this type 
            // is the cv-qualified iterated type (as opposed to value_type).
            // We want to preserve the cv-qualification because the iterator 
            // might be a const_iterator e.g. iterating a const 
            // std::pair<> but std::pair<>::second_type isn't automatically 
            // const just because the pair is const - access_member_f is 
            // preserving the cv-qualification, otherwise compiler errors will 
            // be the result
            typename std::tr1::remove_reference<
                typename std::iterator_traits<Iterator>::reference
            >::type, 
            typename std::iterator_traits<Iterator>::value_type::second_type, 
            &std::iterator_traits<Iterator>::value_type::second
        >, 
        Iterator
    >
{
    typedef boost::transform_iterator<
        access_member_f<
            typename std::tr1::remove_reference<
                typename std::iterator_traits<Iterator>::reference
            >::type, 
            typename std::iterator_traits<Iterator>::value_type::second_type, 
            &std::iterator_traits<Iterator>::value_type::second
        >, 
        Iterator
    > baseclass;

public:
    accessing_second_iterator(): 
        baseclass()
    {}

    // note: allow implicit conversion from Iterator
    accessing_second_iterator(Iterator it): 
        baseclass(it)
    {}
};

Это приводит к еще более чистому коду:

void run_map_value()
{
  typedef map<int, string> a_map_t;
  a_map_t a_map;
  a_map[0] = "zero";
  a_map[1] = "one";
  a_map[2] = "two";

  typedef accessing_second_iterator<a_map_t::const_iterator> ia_t;
  // note: specify the iterator adaptor type explicitly as template type, enabling 
  // implicit conversion from begin()/end()
  copy<ia_t>(a_map.begin(), a_map.end(),
    ostream_iterator<string>(cout, "\n")
  );
}
7
ответ дан 30 November 2019 в 10:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: