Since C++11 we can write lambdas such as:
auto foo = [a, b]() { return a+b; };
with a square-bracketed capture clause, in which items are separated by commas. In C++17 we'll be able to use structured bindings:
for (const auto& [name, description] : planet_descriptions) {
std::cout << "Planet " << name << ":\n" << description << "\n\n";
}
which is another example of a comma-separated square-bracketed clause.
Yet, we cannot override a class' operator[]
to take several parameters, e.g. this:
template<typename V, typename I, typename J>
const V& operator[](I i, J j) const {
return data_[width() * i + j];
}
will not compile.
I know there are workarounds - many are mentioned here:
C++ [] array operator with multiple arguments?
But - why are the former part of the language while the latter impossible even as an overload at the programmer's discretion? Is it simply because nobody has proposed otherwise, or is there some specific reason for it?
Notes:
- Yes, of course this will create ambiguity / incompatibility with using the comma operator in a call to a unary
operator[]
:x[a, b]
would be eitheroperator[](operator,(a,b))
oroperator[](a,b)
. However, we have sort-of the same ambiguity with round brackets:foo(a,b)
might be a call to a binaryfoo()
witha
andb
, or it might befoo(operator,(a,b)
. The language standard simply decrees it's the former rather than the latter (or that the former should be preferred); the same preference could be decreed for square brackets. In fact, if I'm not mistaken that will not actually break any existing code - since existing code won't have a binaryoperator[]
to prefer. - The example binary
operator[]
is just an example, not something I want to implement.