2

In algorithms where membership tests are frequent, I really miss the infix ∈ operator, and I like to use the % operator instead. It works well with the regular containers, but for some reason clang and gcc reject it for initializer_lists. I have no doubt they are "right" in the sense that the standard is certainly rejecting this. But why?

#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
}
akim
  • 8,255
  • 3
  • 44
  • 60
  • 1
    Rather than `%`, perhaps a [named operator](https://github.com/klmr/named-operator) like `` would be more intuitive? – chris May 07 '15 at 15:03
  • I don´t hate operator overloading, but integer modulo and element-of of a set are completely different things. Is it really a problem to use a normal function instead of making confusing operator stuff? – deviantfan May 07 '15 at 15:04
  • `template using il=std::initializer_list;` could help. `"foo" % il{"foo","bar"}`. This requires mentioning the type. – Yakk - Adam Nevraumont May 07 '15 at 19:08
  • @deviantfan Well, that's because you are used to read `%` as only modulo, that's all. Were you shocked to see bit-shifting used for streams? Boost already uses `%` for serialization, or for feeding printf-like formats. Languages have been contained into ASCII for years and played ASCII art to introduce new operators. Aren't you disturbed by the lambda of Haskell spelled '\'? Since `∈` is not ASCII, `%` is reasonable, and it is actually the character used in the Claire programming language to denote membership test. – akim May 12 '15 at 06:50
  • @chris Well, why not, I supposed you are referring to "Named operators". In which case, you are referring to tricks played with `operator<` and `operator>`, in which case I'm back to square one: operators don't play with initializer_lists in c++. – akim May 12 '15 at 06:54
  • @akim `Were you shocked ... Aren't you disturbed ...` What´s your problem? And yes, of course I´m used to % as modulo, because that´s what it was in C and C++ since ever. And that´s why. C++ is not Claire or anything, C++ is C++, and people using C++ will expect it to behave like C++. If you like redefining everything, you´ll have a hard time programming in teams, or more generally that other people understand your code. – deviantfan May 12 '15 at 07:06
  • @deviantfan Apparently you've been hurt by my words. I'm sorry about that, it was not my intention. – akim May 12 '15 at 08:41
  • @deviantfan `I don´t hate ... Is it really a problem ... instead of making confusing operator stuff`, apparently you don't like people answering the way you speak to them – fjardon May 12 '15 at 14:10

1 Answers1

7

A braced-init-list isn't an expression, and can only appear in certain places. Those places include function arguments, but not the operands of most operators.

In some cases, it can be used to create a temporary initializer_list, but it isn't itself an initializer_list.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • 1
    Or as Scott likes to put it: "Braced initializers have no type … braced initializers have not type … braced initializers have no type … … unless they do!" – MFH May 07 '15 at 21:24
  • Hi Mike. Again, I have no doubt that the standard says so. My question is why? What difference is there here bw a function call and using an operator? What did the committee ruled operators out? – akim May 11 '15 at 07:10
  • OK, the answer is given here: http://stackoverflow.com/a/11445905/1353549. In short, the problem is that the grammar would then have generate really bad conflicts in LR parsers. – akim May 11 '15 at 07:16