【问题标题】:Why can't I use operator% on initializer_list? [duplicate]为什么我不能在 initializer_list 上使用 operator%? [复制]
【发布时间】:2015-05-07 15:00:28
【问题描述】:

在成员资格测试频繁的算法中,我真的很怀念中缀 ∈ 运算符,而我喜欢使用 % 运算符。它适用于常规容器,但由于某种原因,clang 和 gcc 拒绝它用于 initializer_lists。我毫不怀疑他们是“正确的”,因为标准肯定拒绝这一点。但为什么呢?

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

/// Whether e ∈ m.
template <typename T, typename U>
inline bool
in(const U& k, const std::initializer_list<T>& m)
{
  return std::find(begin(m), end(m), k) != std::end(m);
}

/// Whether e ∈ m.
template <typename T, typename U>
inline bool
operator%(const U& k, const std::initializer_list<T>& m)
{
  return in(k, m);
}

/// Whether e ∈ m.
template <typename T, typename U>
inline bool
operator%(const U& k, const std::vector<T>& m)
{
  return in(k, m);
}

int main()
{
  using strings = std::vector<std::string>;
  std::cout << ("foo" % strings{"foo", "bar"}) << std::endl;
  std::cout << in("foo", {"foo", "bar"}) << std::endl;

  std::cout << ("foo" % {"foo", "bar"}) << std::endl;  // fails
}

【问题讨论】:

  • 比起%,或许像&lt;in&gt;这样的named operator会更直观?
  • 我不讨厌运算符重载,但是整数模和集合的元素是完全不同的东西。使用普通函数而不是制造令人困惑的运算符真的有问题吗?
  • template&lt;class T&gt; using il&lt;T&gt;=std::initializer_list&lt;T&gt;; 可以提供帮助。 "foo" % il&lt;std::string&gt;{"foo","bar"}。这需要提及类型。
  • @deviantfan 好吧,那是因为您习惯于将 % 视为仅模数,仅此而已。看到用于流的位移,您是否感到震惊? Boost 已经使用% 进行序列化,或提供类似 printf 的格式。多年来,语言一直被包含在 ASCII 中,并发挥 ASCII 艺术来引入新的运算符。你不被 Haskell 的 lambda 拼写为 '\' 所困扰吗?由于不是ASCII,所以%是合理的,实际上是Claire编程语言中用来表示成员资格测试的字符。
  • @chris 好吧,为什么不呢,我想您指的是“命名运算符”。在这种情况下,您指的是使用operator&lt;operator&gt; 玩的技巧,在这种情况下,我回到第一个问题:运算符不会在c++ 中使用initializer_lists。

标签: c++ c++11 operator-overloading initializer-list


【解决方案1】:

braced-init-list 不是表达式,只能出现在某些地方。这些地方包括函数参数,但不包括大多数运算符的操作数。

在某些情况下,它可以用来创建一个临时的initializer_list,但它本身并不是一个initializer_list

【讨论】:

  • 或者正如 Scott 喜欢说的那样:“大括号初始化器没有类型……大括号初始化器没有类型……大括号初始化器没有类型……除非他们有!”
  • 嗨,迈克。同样,我毫不怀疑标准是这样说的。我的问题是为什么?函数调用和使用运算符有什么区别?委员会排除了运营商的哪些因素?
  • 好的,答案在这里给出:stackoverflow.com/a/11445905/1353549。简而言之,问题在于语法会在 LR 解析器中产生非常严重的冲突。
猜你喜欢
  • 2014-12-10
  • 1970-01-01
  • 1970-01-01
  • 2020-08-26
  • 2017-05-27
  • 2018-07-11
  • 1970-01-01
  • 2018-04-06
  • 2014-08-19
相关资源
最近更新 更多