Opened 8 years ago
Closed 4 years ago
#10133 closed Bugs (fixed)
boost 1.55 breaks fusion map arrays
Reported by: | Owned by: | Joel de Guzman | |
---|---|---|---|
Milestone: | Boost 1.68.0 | Component: | fusion |
Version: | Boost 1.55.0 | Severity: | Regression |
Keywords: | Cc: |
Description
The attached code compiles and runs on 1.53 with the attached output. It fails to build on 1.55 with the attached error. (gcc 4.8.2)
build with:
g++ fusion_map.cpp -o fusion_map -std=c++11
Attachments (3)
Change History (6)
by , 8 years ago
Attachment: | fusion_map.cpp added |
---|
by , 8 years ago
Attachment: | fusion_map_1.53 added |
---|
by , 8 years ago
Attachment: | fusion_map.error.1.55 added |
---|
comment:1 by , 8 years ago
comment:2 by , 8 years ago
I believe that it is not a fusion's bug.
The constructor of map
will take their arguments by Universal References, like template <class... T> map(T &&...)
, to accept any types and any value categories, i.e. perfect forwarding.
However, compiler cannot deduce the argument type from brace-enclosed initializer, see below.
n3337 14.8.2.1 [temp.deduct.call] p.1 sais:
If removing references and cv-qualifiers from P gives std::initializer_list<P 0 > for some P 0 and the argument is an initializer list (8.5.4), then deduction is performed instead for each element of the initializer list, taking P 0 as a function template parameter type and the initializer element as its argument. Otherwise, an initializer list argument causes the parameter to be considered a non-deduced context (14.8.2.5).
and 14.8.2.5 [temp.deduct.type] p.4 sais:
If a template parameter is used only in non-deduced contexts and is not explicitly specified, template argument deduction fails.
comment:3 by , 4 years ago
Milestone: | To Be Determined → Boost 1.68.0 |
---|---|
Resolution: | → fixed |
Status: | new → closed |
The problem, function returns array will be resolved in next release, by https://github.com/boostorg/fusion/pull/177 . And another issue, brace initializer is now handled by https://github.com/boostorg/fusion/issues/165 .
So I close this ticket with resolved.
After a discussion on the mailing list, it was determined that my use of for_each is not correct. The library should not have stepped through each item of an array in a fusion map but rather send the whole array as a type to the function called on each value. It appears that this has been fixed in 1.55.
I had a discussion on the mailing list with Agustin quoted below:
I missed the part where
for_each
was invoking the callable on each element of the array, that is not how it is supposed to be. You are right that making a recursive callable is the correct way to obtain that behavior. --This suggests that in reality what I was doing before was actually the bug, and that 1.55 has the correct behavior.
One issue that we did find, however, is that fusion maps with std::array<T> types cannot have static initializers with 1.55.
For example,
This compiles with 1.53 but not 1.55. The {{3, 4}} is the issue.
Also interestingly enough, I have to put braces around "test" with 1.53 but not 1.55.