编译错误:在 Boost.Range / MPL 中没有名为 'type' 的类型



在编译下面的代码时,编译器(clang 10.0.1)在Boost的深处生成error: no type named 'type'...boost::adaptors::transformed的范围库依赖关系

我应该如何改变我的模板函数result_data_type,以避免这个编译器错误?

源代码为;

struct request_data {
std::string data;
size_t      length = 0;
};
struct error {
std::string message;
};
template <typename T> 
using result_value = boost::variant<T, error>;
template <typename T> 
auto result_data_type(result_value<T>&& input) -> result_value<T> {
return boost::apply_visitor(
make_visitor([](const T& req) { return req; },
[](const error&) {
throw std::runtime_error("SHOULD_NEVER_HAPPEN");
return T();
}),
input);
};
BOOST_AUTO_TEST_CASE(template_test) {
using result_data = result_value<request_data>;
const auto vec_in =
std::vector<result_data>{result_data{request_data{"Hi", 2}},
result_data{request_data{"there!", 6}}};
auto vec_out =
vec | boost::adaptors::transformed(result_data_type<request_data>);
}

完整误差输出为;

[main] Building folder: aljam 
[build] Starting build
[proc] Executing command: /Applications/CMake.app/Contents/bin/cmake --build /Users/alan/github/aljam/build --config Debug --target aljam -- -j 6
[build] Scanning dependencies of target aljam
[build] [  2%] Building CXX object CMakeFiles/aljam.dir/cpp_playground/aljam.cpp.o
[build] In file included from /Users/alan/github/aljam/cpp_playground/aljam.cpp:9:
[build] In file included from /Users/alan/github/boost_1_73_0/boost/test/unit_test.hpp:18:
[build] In file included from /Users/alan/github/boost_1_73_0/boost/test/test_tools.hpp:46:
[build] In file included from /Users/alan/github/boost_1_73_0/boost/test/tools/old/impl.hpp:28:
[build] In file included from /Users/alan/github/boost_1_73_0/boost/numeric/conversion/conversion_traits.hpp:13:
[build] In file included from /Users/alan/github/boost_1_73_0/boost/numeric/conversion/detail/conversion_traits.hpp:17:
[build] In file included from /Users/alan/github/boost_1_73_0/boost/numeric/conversion/detail/meta.hpp:16:
[build] /Users/alan/github/boost_1_73_0/boost/mpl/eval_if.hpp:38:26: error: no type named 'type' in 'boost::result_of<boost::variant<aljam::request_data, aljam::error> (*const &(const boost::variant<aljam::request_data, aljam::error> &))(boost::variant<aljam::request_data, aljam::error> &&)>'
[build]     typedef typename f_::type type;
[build]             ~~~~~~~~~~~~~^~~~
[build] /Users/alan/github/boost_1_73_0/boost/iterator/iterator_adaptor.hpp:149:9: note: in instantiation of template class 'boost::mpl::eval_if<boost::is_same<boost::use_default, boost::use_default>, boost::result_of<boost::variant<aljam::request_data, aljam::error> (*const &(const boost::variant<aljam::request_data, aljam::error> &))(boost::variant<aljam::request_data, aljam::error> &&)>, boost::mpl::identity<boost::use_default> >' requested here
[build]       : mpl::eval_if<
[build]         ^
[build] /Users/alan/github/boost_1_73_0/boost/iterator/transform_iterator.hpp:48:26: note: in instantiation of template class 'boost::iterators::detail::ia_dflt_help<boost::use_default, boost::result_of<boost::variant<aljam::request_data, aljam::error> (*const &(const boost::variant<aljam::request_data, aljam::error> &))(boost::variant<aljam::request_data, aljam::error> &&)> >' requested here
[build]         typedef typename ia_dflt_help<
[build]                          ^
[build] /Users/alan/github/boost_1_73_0/boost/iterator/transform_iterator.hpp:80:40: note: in instantiation of template class 'boost::iterators::detail::transform_iterator_base<boost::variant<aljam::request_data, aljam::error> (*)(boost::variant<aljam::request_data, aljam::error> &&), std::__1::__wrap_iter<const boost::variant<aljam::request_data, aljam::error> *>, boost::use_default, boost::use_default>' requested here
[build]     : public boost::iterators::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
[build]                                        ^
[build] /Users/alan/github/boost_1_73_0/boost/range/adaptor/transformed.hpp:33:30: note: in instantiation of template class 'boost::iterators::transform_iterator<boost::variant<aljam::request_data, aljam::error> (*)(boost::variant<aljam::request_data, aljam::error> &&), std::__1::__wrap_iter<const boost::variant<aljam::request_data, aljam::error> *>, boost::use_default, boost::use_default>' requested here
[build]                     typename transform_iterator<P, It>::reference
[build]                              ^
[build] /Users/alan/github/boost_1_73_0/boost/range/adaptor/transformed.hpp:42:26: note: in instantiation of template class 'boost::range_detail::transform_iterator_gen<boost::variant<aljam::request_data, aljam::error> (*)(boost::variant<aljam::request_data, aljam::error> &&), std::__1::__wrap_iter<const boost::variant<aljam::request_data, aljam::error> *> >' requested here
[build]                 typename transform_iterator_gen<
[build]                          ^
[build] /Users/alan/github/aljam/cpp_playground/aljam.cpp:564:13: note: in instantiation of template class 'boost::range_detail::transformed_range<boost::variant<aljam::request_data, aljam::error> (*)(boost::variant<aljam::request_data, aljam::error> &&), const std::__1::vector<boost::variant<aljam::request_data, aljam::error>, std::__1::allocator<boost::variant<aljam::request_data, aljam::error> > > >' requested here
[build]         vec | boost::adaptors::transformed(result_data_type<request_data>);
[build]             ^
[build] In file included from /Users/alan/github/aljam/cpp_playground/aljam.cpp:19:
[build] In file included from /Users/alan/github/aljam/functional/range.hpp:17:
[build] /Users/alan/github/boost_1_73_0/boost/range/adaptor/transformed.hpp:57:20: error: no type named 'reference' in 'boost::iterators::transform_iterator<boost::variant<aljam::request_data, aljam::error> (*)(boost::variant<aljam::request_data, aljam::error> &&), std::__1::__wrap_iter<const boost::variant<aljam::request_data, aljam::error> *>, boost::use_default, boost::use_default>'
[build]                 >::reference
[build]                 ~~~^~~~~~~~~
[build] /Users/alan/github/aljam/cpp_playground/aljam.cpp:564:13: note: in instantiation of template class 'boost::range_detail::transformed_range<boost::variant<aljam::request_data, aljam::error> (*)(boost::variant<aljam::request_data, aljam::error> &&), const std::__1::vector<boost::variant<aljam::request_data, aljam::error>, std::__1::allocator<boost::variant<aljam::request_data, aljam::error> > > >' requested here
[build]         vec | boost::adaptors::transformed(result_data_type<request_data>);
[build]             ^
[build] In file included from /Users/alan/github/aljam/cpp_playground/aljam.cpp:19:
[build] In file included from /Users/alan/github/aljam/functional/range.hpp:17:
[build] /Users/alan/github/boost_1_73_0/boost/range/adaptor/transformed.hpp:96:19: error: no matching constructor for initialization of 'transformed_range<boost::variant<aljam::request_data, aljam::error> (*)(boost::variant<aljam::request_data, aljam::error> &&), const std::__1::vector<boost::variant<aljam::request_data, aljam::error>, std::__1::allocator<boost::variant<aljam::request_data, aljam::error> > > >'
[build]            return transformed_range<UnaryFunction, const SinglePassRange>(
[build]                   ^
[build] /Users/alan/github/aljam/cpp_playground/aljam.cpp:564:13: note: in instantiation of function template specialization 'boost::range_detail::operator|<std::__1::vector<boost::variant<aljam::request_data, aljam::error>, std::__1::allocator<boost::variant<aljam::request_data, aljam::error> > >, boost::variant<aljam::request_data, aljam::error> (*)(boost::variant<aljam::request_data, aljam::error> &&)>' requested here
[build]         vec | boost::adaptors::transformed(result_data_type<request_data>);
[build]             ^
[build] /Users/alan/github/boost_1_73_0/boost/range/adaptor/transformed.hpp:62:13: note: candidate constructor not viable: no known conversion from 'boost::variant<aljam::request_data, aljam::error> (*const)(boost::variant<aljam::request_data, aljam::error> &&)' to 'boost::range_detail::transformed_range<boost::variant<aljam::request_data, aljam::error> (*)(boost::variant<aljam::request_data, aljam::error> &&), const std::__1::vector<boost::variant<aljam::request_data, aljam::error>, std::__1::allocator<boost::variant<aljam::request_data, aljam::error> > > >::transform_fn_type' (aka 'int') for 1st argument
[build]             transformed_range(transform_fn_type f, R& r)
[build]             ^
[build] /Users/alan/github/boost_1_73_0/boost/range/adaptor/transformed.hpp:40:16: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided
[build]         struct transformed_range :
[build]                ^
[build] /Users/alan/github/boost_1_73_0/boost/range/adaptor/transformed.hpp:40:16: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided
[build] 3 errors generated.
[build] make[3]: *** [CMakeFiles/aljam.dir/cpp_playground/aljam.cpp.o] Error 1
[build] make[2]: *** [CMakeFiles/aljam.dir/all] Error 2
[build] make[1]: *** [CMakeFiles/aljam.dir/rule] Error 2
[build] make: *** [aljam] Error 2
[build] Build finished with exit code 2

这似乎是一个没有帮助的错误消息,完全忽略了问题的原因。

将最后一行重写为

auto vec_out = vec_in | boost::adaptors::transformed([](auto& result_data){ return result_data_type<request_data>(result_data); });

我收到了更有用的错误信息:

test.cc:68:118: error: cannot bind rvalue reference of type ‘result_value<request_data>&&’ {aka ‘std::variant<request_data, error>&&’} to lvalue of type ‘const std::variant<request_data, error>’

result_data_type更改为const result_value<T>&而不是result_value<T>&&修复编译错误。

相关内容

最新更新