C++ 超载>&燃气轮机;运算符并使用自定义类型的初始值设定项列表初始化

C++ 超载>&燃气轮机;运算符并使用自定义类型的初始值设定项列表初始化,c++,map,operator-overloading,initializer-list,C++,Map,Operator Overloading,Initializer List,我一直在尝试制作一个非常简单的映射容器,我认为能够像这样初始化它会很好: Hash table = { "name1" >> value, "name2" >> value2, "name3" >> value3, "name4" >> value4 }; 我将如何进行这项工作,首先是制作一对(duo)数据结构,它将 保留每个元素的名称和值,重载>

我一直在尝试制作一个非常简单的映射容器,我认为能够像这样初始化它会很好:

Hash table = {  "name1" >> value,
                "name2" >> value2,
                "name3" >> value3,
                "name4" >> value4  };
我将如何进行这项工作,首先是制作一对(duo)数据结构,它将 保留每个元素的名称和值,重载>>运算符以使用名称和值参数返回duo,并通过使用初始值设定项\u列表构造duo元素的向量为哈希类创建一个构造函数以对其进行初始化。然后使用二进制搜索方法检索所需元素

不幸的是,我从一开始就撞到了墙。 在我开始编写所有代码之前,我想确保重载被正确使用,事实上这是一个明智的决定,因为显然它们不是

这项工作:

#include <iostream>
#include <string>
#include <vector>
#include <initializer_list>

struct duo {
  duo(const std::string key,int value) :key(key) ,value(value) {};
  const std::string key;
  int value;
};

struct Hash {
  std::vector<duo> lister;
  Hash(std::initializer_list<duo> passed) :lister(passed) {};
};

duo operator >> (const std::string& id,int value) {
  return duo(id,value);
}

int main(){
  duo object1("test",1);
  Hash table = {object1};
  std::cout << table.lister[0].key << table.lister[0].value;
}
#包括
#包括
#包括
#包括
结构二重奏{
duo(const std::string key,int value):key(key),value(value){};
常量std::字符串键;
int值;
};
结构散列{
向量列表器;
Hash(std::initializer_list passed):lister(passed){};
};
duo运算符>>(常量标准::字符串和id,int值){
返回duo(id、值);
}
int main(){
第1项(“测试”,1);
哈希表={object1};
std::cout>(常量std::字符串id,int值){
返回duo(id、值);
}
int main(){
哈希表={“test1”>>1};

std::cout运算符,因为我无法重载基元类型。但这似乎不是一个解决方案。是否有任何方法可以在不将字符串文本显式转换为std::string的情况下实现所需的效果?

显式构造
字符串将解决此问题:

int main(){
  Hash table = {std::string("test1") >> 1};
  std::cout << table.lister[0].key << table.lister[0].value;
}
您可能会认为,您可以通过设计以下内容来避免显式构造:

template <size_t N> duo operator >> (const char (&ary)[N], int id)
{
  return duo (std::string (ary), id);
}
Hash table = {"test1" <MapTo> 1};

但是不能,因为C++不允许对指针(或任何原始)类型重写<代码>运算符> <代码>。如果你尝试这个,你将得到一个沿着“必须有类或枚举类型的参数”的编译器错误。为了提供操作符重载,你必须提供至少一个类或枚举类型的参数。



让我们考虑一下。我们不能为std::string和int使用您定义的
运算符,但您可以尝试将其与参数const char[]和int一起使用。您需要让编译器知道第一个参数是std::string。请尝试
{“test1”s>>1}

对于两种基本类型,
char const*
int
,您重载了
操作符>
;这是通过语言实现的。要使其以当前形式工作,需要从第一个参数显式创建
std::string

Hash table = {std::string("test1") >> 1};
当然,另一个选择是放弃这种初始化语法,而坚持使用逗号分隔的对

#include <iostream>
#include <string>
#include <vector>
#include <initializer_list>
#include <utility>

using duo = std::pair<std::string, int>;

struct Hash {
  std::vector<duo> lister;
  Hash(std::initializer_list<duo> passed) :lister(passed) {};
};

int main(){
  Hash table = {{"test1", 1}, {"test2", 2}};
  std::cout << table.lister[0].first << table.lister[0].second;
}
#包括
#包括
#包括
#包括
#包括
使用duo=std::pair;
结构散列{
向量列表器;
Hash(std::initializer_list passed):lister(passed){};
};
int main(){
哈希表={{“test1”,1},{“test2”,2};

std::难道我不知道显式转换可以解决问题。我想知道如何达到预期效果。@JohnDibling我很抱歉。
template
的作用是什么?@Veritas:请参阅我的下一次编辑。我可能已经找到了与您想要的接近的内容。@Siidheesh:这允许传递字符数组,而不会使其降级到某个点呃,因此保持数组的大小是完整的。回过头来看,这并不是严格意义上的。这个标准C++ + GCC不会接受它,我在引用中找不到它。不,它不是,所以任何一个都需要说STD::string(Test1)。显式地或定义s或_的后缀。有没有办法在不显式地将其转换为std::string的情况下达到预期效果?@Veritas我添加了一个替代解决方案,但它不使用您的
操作符>
。我不知道没有显式构造字符串的情况下如何使该操作符工作。这是我担心的。我可以找到许多替代方案,但我必须扔掉干净的初始化外观。
Hash table = {"test1" <MapTo> 1};
template <size_t N> std::string operator < (const char (&ary)[N], Something op)
class HashOperation
{
public:
  template <size_t N> std::string cvt (const char (&ary)[N]) const
  {
    return std::string (ary);
  }
} MapTo;


template <size_t N> std::string operator < (const char (&ary)[N], HashOperation op) 
{
  return op.cvt (ary);
}
duo operator> (const std::string& key, int value)
{
  return duo (key, value);
}
#include <iostream>
#include <string>
#include <vector>
#include <initializer_list>

struct duo {
  duo(const std::string key,int value) :key(key) ,value(value) {};
  template <size_t N> duo (const char (&ary)[N], int value) : key (ary), value (value) {};
  const std::string key;
  int value;
};

struct Hash {
  std::vector<duo> lister;
  Hash(std::initializer_list<duo> passed) :lister(passed) {};
    };


class HashOperation
{
public:
  template <size_t N> std::string cvt (const char (&ary)[N]) const
  {
    return std::string (ary);
  }
} MapTo;


template <size_t N> std::string operator < (const char (&ary)[N], HashOperation op)
{
  return op.cvt (ary);
}

duo operator> (const std::string& key, int value)
{
  return duo (key, value);
}

int main(){
  Hash table =
  {
    "test1" <MapTo> 1,
    "test2" <MapTo> 2
  };

  std::cout << table.lister[0].key << table.lister[0].value;
}
Hash table = {std::string("test1") >> 1};
#include <iostream>
#include <string>
#include <vector>
#include <initializer_list>
#include <utility>

using duo = std::pair<std::string, int>;

struct Hash {
  std::vector<duo> lister;
  Hash(std::initializer_list<duo> passed) :lister(passed) {};
};

int main(){
  Hash table = {{"test1", 1}, {"test2", 2}};
  std::cout << table.lister[0].first << table.lister[0].second;
}