在模板中标记 boost::bimap - 它们有效吗?
Tagged boost::bimap in templates - do they work?
我在模板化的 class 中嵌入了 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 );
}
};
我想将标签封装在模板 class 中,因为它们不需要在 class 之外为人所知。理想情况下它们应该是私有的,但为了避免访问权限产生任何问题,它们被声明为 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 需要完全限定,从成为模板化 class 的一部分,如下所示。
auto ByAddress = TheBimap.by< Test<TemplateParameter>::Label1 >().find( "TheGivenAdddress" );
但是产生了完全相同的错误。 问题一:有人明白为什么吗?
使用模板class测试的真正问题和原因是我希望标签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;
同样,通过标签访问地图的两行都会产生上述编译错误。在重写代码以使用"left"和"right"视图之前,如果有人能帮助我理解就好了问题2:为什么不能在定义中使用模板参数标记类型的?
感谢所有输入!
第二种情况需要template
资格。原因是 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
那里的资格。
演示
#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");
}
要真正将标签类型保留在 class 本地,请添加
struct key_idx;
struct value_idx;
(无需 定义 它们)。看看吧live
我在模板化的 class 中嵌入了 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 );
}
};
我想将标签封装在模板 class 中,因为它们不需要在 class 之外为人所知。理想情况下它们应该是私有的,但为了避免访问权限产生任何问题,它们被声明为 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 需要完全限定,从成为模板化 class 的一部分,如下所示。
auto ByAddress = TheBimap.by< Test<TemplateParameter>::Label1 >().find( "TheGivenAdddress" );
但是产生了完全相同的错误。 问题一:有人明白为什么吗?
使用模板class测试的真正问题和原因是我希望标签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;
同样,通过标签访问地图的两行都会产生上述编译错误。在重写代码以使用"left"和"right"视图之前,如果有人能帮助我理解就好了问题2:为什么不能在定义中使用模板参数标记类型的?
感谢所有输入!
第二种情况需要template
资格。原因是 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
那里的资格。
演示
#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");
}
要真正将标签类型保留在 class 本地,请添加
struct key_idx;
struct value_idx;
(无需 定义 它们)。看看吧live