I'm working with a set of custom C++ libraries that provides a type representing a sequence. There's an overloaded operator+
that takes in two sequences and concatenates them, and an initializer taking in a std::intializer_list
that can be used to initialize the sequence with a list of values. Each of these functions works well on its own, but for some reason they don't play well together.
Here's a reduced test case that shows off the issue:
#include <iostream>
#include <initializer_list>
using namespace std;
struct InitListConstructible {
InitListConstructible() = default;
InitListConstructible(std::initializer_list<int> elems) {
// do something
}
};
InitListConstructible operator+ (InitListConstructible lhs,
InitListConstructible rhs) {
return {};
}
int main() {
/* Totally fine - use initializer list constructor. */
InitListConstructible lhs = { 1, 2, 3 };
/* Totally fine - use overloaded + operator. */
auto legit = lhs + lhs;
/* Totally fine - second argument constructed from initializer list. */
freeFunction(lhs, { 1, 2, 3 });
/* Totally fine - explicit call to operator+. */
auto alsoLegit = operator+ (lhs, { 1, 2, 3 });
/* Not okay - reports error about expected primary-expression. */
auto error = lhs + { 1, 2, 3 };
return 0;
}
Here, the type InitListConstructible
is a simple struct that has a default constructor and an initializer list constructor. There is also an overloaded +
operator that takes in two InitListConstructible
objects and returns a third.
In main
, I can see that the initializer list constructor works just great, as does the overloaded +
operator. It's completely legit call a function that takes in two InitListConstructible
s where the second is initialized from a brace-enclosed expression.
However, the line
auto error = lhs + { 1, 2, 3 };
does not compile, and it reports an error about a missing primary-expression. This leads me to believe that the language syntax just doesn't allow for things like this.
My questions are as follows:
- Is my analysis of the issue - that the language spec just doesn't allow brace-enclosed lists in expression contexts - correct?
- Is there a fundamental reason why this isn't permitted, given that the brace-enclosed expression could have its type deduced from the type of the argument to
operator+
? My suspicion is that this has to do with the fact that every expression in C++ needs to have a well-defined type that doesn't depend on context, and if that's correct I'd appreciate a confirmation.