标签中的boost :: bimap – 它们有效吗?

我在一个模板化的类中嵌入了一个boost :: bimap,经过多次试验和错误后,我发现了一些可以编译的东西和一些没有编译的东西.我正在使用g(GCC)4.9.2 20150212(Red Hat 4.9.2-6)和Boost 1.55.我将给出示例1中的完整代码,并且仅给出示例2和示例3的更改部分.该函数没有做任何有用的事情,只是在这里测试语法和编译器.

编译的示例1(完整列表):

#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 );
  }
};

我想将标签封装在模板类中,因为不需要在类之外知道它们.理想情况下,它们应该是私有的,但为了避免访问权限产生任何问题,它们被声明为public.

示例2不编译(除外):

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;

标签访问bimap的两行都会产生以下消息:

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

这可以理解为Label1需要完全限定,作为模板类的一部分,如下所示.

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

但是产生了同样的错误.问题1:有谁理解为什么?

使用模板类Test的真正问题和原因是我希望Label 1的类型是模板参数.因此,回到示例1并仅使用template参数替换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:为什么不能在标记类型的定义中使用模板参数?

感谢所有输入!

最佳答案 第二种情况需要模板鉴定.原因是Label1和Label2现在是依赖名称.

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

Where and why do I have to put the “template” and “typename” keywords?

Question 2: Why is it not possible to use a template parameter in the definition of the tagged type?

同样的道理.您可能还需要typename资格.

演示

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

点赞