Tagged boost :: bimap in templates - do they work?

I am implementing boost :: bimap in a template class, and after a lot of trial and error, I discovered something that compiles and something that does not. I am using g ++ (GCC) 4.9.2 20150212 (Red Hat 4.9.2-6) and Boost 1.55. I will give the full code in example 1 and only the modified parts for example 2 and example 3. The function does nothing useful, just checking the syntax and compiler here.

Example 1 that compiles (full list):

#include <string>
#include <boost/bimap/bimap.hpp>
#include <boost/bimap/set_of.hpp>
#include <boost/bimap/unordered_set_of.hpp>
#include <boost/bimap/tags/tagged.hpp>

typedef double Address;

  struct Label1 {};
  struct Label2 {};

template< class TemplateParameter >
class Test
{
 private:

  typedef boost::bimaps::tagged< std::string, Label1 >  KeyType;
  typedef boost::bimaps::tagged< Address, Label2 > ValueType;

// No changes after this line in Example 2 or Example 3

  typedef boost::bimaps::unordered_set_of< KeyType > KeySet;
  typedef boost::bimaps::set_of< ValueType > ValueSet;

  typedef boost::bimaps::bimap < KeySet, ValueSet > BidirectionalMap;

  typedef typename BidirectionalMap::value_type Record;

  // Create the bimap

  BidirectionalMap TheBimap;

  void aFunction ( const Address & AnAddress, 
           const TemplateParameter & Parameters )
  {
    auto NewRecord = TheBimap.insert( Record( "TheGivenAdddress", AnAddress ) );
    auto ByAddress = TheBimap.by< Label1 >().find( "TheGivenAdddress" );
    auto ByNumber = TheBimap.by< Label2 >().find( AnAddress );
  }
};

I would like to encapsulate labels inside the template class, since there is no need for them to be known outside the class. Ideally, they should be closed, but to avoid permissions to access them, they are declared public.

Example 2 that does not compile (except):

typedef double Address;

template< class TemplateParameter >
class Test
{
public:

  struct Label1 {};
  struct Label2 {};

private:

  typedef boost::bimaps::tagged< std::string, Label1 >  KeyType;
  typedef boost::bimaps::tagged< Address, Label2 > ValueType;

, , :

error: expected primary-expression before ‘>’ token
 auto ByAddress = TheBimap.by< Label1 >().find( "TheGivenAdddress" );

, Label1 , , .

auto ByAddress = TheBimap.by< Test<TemplateParameter>::Label1 >().find( "TheGivenAdddress" );

. 1: - , ?

, , 1 . , 1 std::string .

3, ():

typedef double Address;

  struct Label1 {};
  struct Label2 {};

template< class TemplateParameter >
class Test
{
private:

  typedef boost::bimaps::tagged< TemplateParameter, Label1 >  KeyType;
  typedef boost::bimaps::tagged< Address, Label2 > ValueType;

, , , . "" "" , , - 2: -?

!

+4
1

template. , Label1 Label2 .

auto ByAddress = TheBimap.template by<Label1>().find("TheGivenAdddress");
auto ByNumber  = TheBimap.template by<Label2>().find(AnAddress);

. " "typename" ?

2: ?

. typename.

Demo

Live On Coliru

#include <string>
#include <boost/bimap/bimap.hpp>
#include <boost/bimap/set_of.hpp>
#include <boost/bimap/unordered_set_of.hpp>
#include <boost/bimap/tags/tagged.hpp>

typedef double Address;

namespace bm = boost::bimaps;

template <class T>
class Test {
  private:
    typedef bm::bimap<
          bm::unordered_set_of<bm::tagged<T,       struct key_idx> >,
          bm::set_of          <bm::tagged<Address, struct value_ix> >
      > BidirectionalMap;

    typedef typename BidirectionalMap::value_type Record;

    BidirectionalMap _theBimap;

  public:
    void aFunction(const Address &anAddress, T const& parameters)
    {
        auto newRecord = _theBimap.insert(Record("TheGivenAdddress", anAddress));
        auto byNumber  = _theBimap.template by<value_ix>().find(anAddress);
        auto byAddress = _theBimap.template by<key_idx>().find(parameters);

        (void) newRecord, (void) byAddress, (void) byNumber;
    }
};

int main() {
    Test<std::string> t;
    t.aFunction(3.14, "hello");
}

,

    struct key_idx;
    struct value_idx;

( ). live

+2

All Articles