`using namespace boost::ut;` breaks piping views that are copied to local variable.
First of all, I am aware that this might be more general problem with views and using namespace and not specific to this library, but if it is somehow fixed, it would increase quality of life for the user.
Expected Behavior
Piping views would not be broken with using namespace boost::ut.
Actual Behavior
Following example (https://godbolt.org/z/1sq4o5s8f) won't compile :
#include <boost/ut.hpp>
#include <ranges>
#include <vector>
#include <iostream>
int main() {
using namespace boost::ut;
const auto vec = std::vector{ 3, 3, 3, 3 };
const auto foo = std::views::transform([](const auto x) { return 2 * x; } );
// Not ok if `using namespace boost::ut` is present
for (const auto x : vec | foo ) {
std::cout << x << "\n";
}
// Ok
for (const auto x : vec | std::views::transform([](const auto x) { return 2 * x; })) {
std::cout << x << "\n";
}
}
Error message from gcc 13.2 with -std=c++20:
<source>: In function 'int main()':
<source>:14:31: error: 'begin' was not declared in this scope
14 | for (const auto x : vec | foo ) {
| ^~~
<source>:14:31: note: suggested alternatives:
In file included from /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/array:44,
from /app/raw.githubusercontent.com/boost-experimental/ut/master/include/boost/ut.hpp:76,
from <source>:1:
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/range_access.h:114:37: note: 'std::begin'
114 | template<typename _Tp> const _Tp* begin(const valarray<_Tp>&) noexcept;
| ^~~~~
In file included from /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/ranges_algobase.h:38,
from /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/ranges_algo.h:38,
from /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/algorithm:63,
from /app/raw.githubusercontent.com/boost-experimental/ut/master/include/boost/ut.hpp:75:
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/ranges_base.h:489:44: note: 'std::ranges::__cust::begin'
489 | inline constexpr __cust_access::_Begin begin{};
| ^~~~~
In file included from /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_iterator_base_types.h:71,
from /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/stl_algobase.h:65,
from /opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/algorithm:60:
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/iterator_concepts.h:984:10: note: 'std::ranges::__cust_access::begin'
984 | void begin(const auto&) = delete;
| ^~~~~
<source>:14:31: error: 'end' was not declared in this scope
14 | for (const auto x : vec | foo ) {
| ^~~
<source>:14:31: note: suggested alternatives:
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/range_access.h:116:37: note: 'std::end'
116 | template<typename _Tp> const _Tp* end(const valarray<_Tp>&) noexcept;
| ^~~
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/ranges_base.h:490:42: note: 'std::ranges::__cust::end'
490 | inline constexpr __cust_access::_End end{};
| ^~~
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/ranges_base.h:137:10: note: 'std::ranges::__cust_access::end'
137 | void end(const auto&) = delete;
| ^~~
Error message from clang 17.0.1 with -std=c++20:
<source>:14:23: error: invalid range expression of type '(lambda at /app/raw.githubusercontent.com/boost-experimental/ut/master/include/boost/ut.hpp:2732:10)'; no viable 'begin' function available
14 | for (const auto x : vec | foo ) {
| ^ ~~~
Steps to Reproduce the Problem
- Try to compile the example
- Remove
using namespace boost::ut; - Try to compile again
Specifications
- Version: V2.0.1
- Platform: Linux
Extra stuff that might or might not be related
These compilation fails came up when trying to produce minimal example to similar problem but not quite the
same. The original problem was that following would find boost::ext::ut::v2_0_0::operators::operator| for the first pipe and then broke piping to std::views::enumerate:
#include <boost/ut.hpp>
// ...
int main() {
using namespace boost::ut;
// ...
auto normalize_factors = std::transform(...);
for (const auto& [i, nfac] : factors_vec | normalize_factors | std::views::enumerate) {
// ...
}/
}
Here is the error message from gcc 13.2:
../tests/test_tensorexpr.cpp:32:74: error: no match for ‘operator|’ (operand types are ‘boost::ext::ut::v2_0_0::operators::operator|<std::vector<idg::Factor>, std::ranges::views::__adaptor::_Partial, std::ranges::views::_Transform, idg::<lambda(const auto:93&)> >(const std::vector<idg::Factor>&, const std::ranges::views::__adaptor::_Partial<std::ranges::views::_Transform, idg::<lambda(const auto:93&)> >&)::<lambda(auto:54)>’ and ‘const std::ranges::views::_Enumerate’)
32 | for (const auto& [i, nfac] : factors_vec | normalize_factors | std::views::enumerate) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~
| | |
| | const std::ranges::views::_Enumerate
| boost::ext::ut::v2_0_0::operators::operator|<std::vector<idg::Factor>, std::ranges::views::__adaptor::_Partial, std::ranges::views::_Transform, idg::<lambda(const auto:93&)> >(const std::vector<idg::Factor>&, const std::ranges::views::__adaptor::_Partial<std::ranges::views::_Transform, idg::<lambda(const auto:93&)> >&)::<lambda(auto:54)>