(重新)命名为std :: pair成员

Ali*_*Ali 25 c++ templates stl typedef traits

而不是写town->first我想写town->name.内联命名访问器(重命名地图迭代器命名std :: pair成员的第一个和第二个)是我到目前为止找到的最佳解决方案.我对命名访问器的问题是类型安全性的丢失: pair<int,double>可能是指struct { int index; double value; }或者struct { int population; double avg_temp; }.任何人都可以提出一个简单的方法,也许类似于特征?

我经常想从一个函数返回一对或一个元组,struct city { string name; int zipcode; }每次引入一个类似的新类型和它的ctor 是非常累人的.我很高兴了解boost和C++ 0x但我需要一个没有提升的纯C++ 03解决方案.

更新

Re andrewdski的问题:是的,一个(假设的)语法就像pair<int=index, double=value>创建一个不同的类型来pair<int=population, double=avg_temp>满足你的要求.我甚至不介意实现一个自定义的对/元组模板类ONCE,只是当我需要一个新类型时,只是将'name traits'模板参数传递给它.我不知道'名称特征'会是什么样子.也许这是不可能的.

Ben*_*igt 18

我不知道你怎么可能做得更好

struct city { string name; int zipcode; };
Run Code Online (Sandbox Code Playgroud)

那里没有什么不必要的.您需要两个成员的类型,您的整个问题的前提是为两个成员指定名称,并且您希望它是一个唯一类型.

你知道聚合初始化语法,对吗?你不需要构造函数或析构函数,编译器提供的就好了.

示例:http://ideone.com/IPCuw


类型安全要求您引入新类型,否则pair<string, int>(名称,邮政编码)和(人口,临时)之间不明确.

在C++ 03中,返回一个新元组需要:

city retval = { "name", zipcode };
return retval;
Run Code Online (Sandbox Code Playgroud)

或编写便利构造函数:

city::city( std::string newName, int newZip ) : name(newName), zipcode(newZip) {}
Run Code Online (Sandbox Code Playgroud)

要得到

return city("name", zipcode);
Run Code Online (Sandbox Code Playgroud)

但是,使用C++ 0x,您将被允许写入

return { "name", zipcode };
Run Code Online (Sandbox Code Playgroud)

并且不需要用户定义的构造函数.

  • 你打败了我.我应该添加`string`,聚合初始化语法将不起作用. (2认同)
  • 可能很好地扩展一般谷歌观众的聚合初始化语法 (2认同)

Vik*_*ehr 6

我想详细说明

struct City : public std::pair<string, int> {
  string& name() { return first; }
  const string& name() const { return first; }
  int& zip() { return second; }
  int zip() const { return second; }
};
Run Code Online (Sandbox Code Playgroud)

是最接近您正在寻找的东西的,尽管struct City { string name; int zipcode; }看起来非常好。

  • 引用问题: _Inline 命名访问器 ([1](http://stackoverflow.com/q/1500064/341970), [2](http://compgroups.net/comp.lang.c++.moderated/Named-std -pair-members))是迄今为止我找到的最好的解决方案_ (2认同)

dal*_*lle 5

虽然不完美,但可以使用标记数据:

template <typename tag_type, typename pair_type>
typename tag_type::type& get(pair_type& p);

typedef std::pair<std::string /*name*/, int /*zipcode*/> city;
struct name { typedef std::string type; };
struct zipcode { typedef int type; };

template <>
std::string& get<name, city>(city& city)
{
   return city.first;
}

template <>
int& get<zipcode, city>(city& city)
{
   return city.second;
}

int main()
{
   city c("new york", 10001);
   std::string n = get<name>(c);
   int z = get<zipcode>(c);
}
Run Code Online (Sandbox Code Playgroud)

但正如本·沃格特所说的那样:struct city { string name; int zipcode; };几乎总会更好.

编辑:模板可能是一个矫枉过正,你可以在命名空间中使用自由函数.这仍然不能解决类型安全问题,因为任何std::pair<T1, T2>类型都与其他类型相同std::pair<T1, T2>:

namespace city
{
   typedef std::pair<std::string /*name*/, int /*zipcode*/> type;

   std::string& name(type& city)
   {
      return city.first;
   }

   int& zipcode(type& city)
   {
      return city.second;
   }
}

int main()
{
   city::type c("new york", 10001);
   std::string n = city::name(c);
   int z = city::zipcode(c);
}
Run Code Online (Sandbox Code Playgroud)