boost::fiber で packaged_task を作成する際に、fixedsize_stack アロケータを指定したい
Boost 1.72 を使っています。
コンパイラは FreeBSD stable/12 上の clang version 8.0.1 です。
boost::fiber を使ったコードを書いていて、packaged_task を作成する際に、スタックサイズを指定したいのですが、スタックアロケータを指定するとコンパイルエラーが出てコンパイルできません。
なんとかする方法はありますでしょうか。
発生している問題・エラーメッセージ
In file included from test_stackallocator.cpp:1: In file included from /usr/include/c++/v1/iostream:38: In file included from /usr/include/c++/v1/ios:216: In file included from /usr/include/c++/v1/__locale:15: In file included from /usr/include/c++/v1/string:505: In file included from /usr/include/c++/v1/string_view:176: In file included from /usr/include/c++/v1/__string:57: In file included from /usr/include/c++/v1/algorithm:644: /usr/include/c++/v1/memory:1515:38: error: no type named 'value_type' in 'boost::context::basic_fixedsize_stack<boost::context::stack_traits>' typedef typename allocator_type::value_type value_type; ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~ /usr/local/include/boost/fiber/future/detail/task_object.hpp:115:22: note: in instantiation of template class 'std::__1::allocator_traits<boost::context::basic_fixedsize_stack<boost::context::stack_traits> >' requested here typedef typename allocator_traits::template rebind_alloc< ^ /usr/local/include/boost/fiber/future/packaged_task.hpp:57:22: note: in instantiation of template class 'boost::fibers::detail::task_object<boost::_bi::bind_t<void, void (*)(std::__1::basic_string<char>, boost::function<void ()>), boost::_bi::list2<boost::_bi::value<std::__1::basic_string<char> >, boost::_bi::value<boost::function<void ()> > > >, boost::context::basic_fixedsize_stack<boost::context::stack_traits>, void>' requested here typename object_type::allocator_type ^ test_stackallocator.cpp:47:12: note: in instantiation of function template speci alization 'boost::fibers::packaged_task<void ()>::packaged_task<boost::_bi::bind _t<void, void (*)(std::__1::basic_string<char>, boost::function<void ()>), boost ::_bi::list2<boost::_bi::value<std::__1::basic_string<char> >, boost::_bi::value<boost::function<void ()> > > >, boost::context::basic_fixedsize_stack<boost::context::stack_traits> >' requested here pack_t pt(std::allocator_arg, fs_t(stacksize), ^ In file included from test_stackallocator.cpp:10: In file included from /usr/local/include/boost/fiber/future/packaged_task.hpp:20: /usr/local/include/boost/fiber/future/detail/task_object.hpp:115:49: error: no member named 'rebind_alloc' in 'std::__1::allocator_traits<boost::context::basic_fixedsize_stack<boost::context::stack_traits> >' typedef typename allocator_traits::template rebind_alloc< ~~~~~~~~~~~~~~~~~~ ^ /usr/local/include/boost/fiber/future/packaged_task.hpp:57:22: note: in instantiation of template class 'boost::fibers::detail::task_object<boost::_bi::bind_t<void, void (*)(std::__1::basic_string<char>, boost::function<void ()>), boost::_bi::list2<boost::_bi::value<std::__1::basic_string<char> >, boost::_bi::value<boost::function<void ()> > > >, boost::context::basic_fixedsize_stack<boost::context::stack_traits>, void>' requested here typename object_type::allocator_type ^ test_stackallocator.cpp:47:12: note: in instantiation of function template specialization 'boost::fibers::packaged_task<void ()>::packaged_task<boost::_bi::bind_t<void, void (*)(std::__1::basic_string<char>, boost::function<void ()>), boost::_bi::list2<boost::_bi::value<std::__1::basic_string<char> >, boost::_bi::value<boost::function<void ()> > > >, boost::context::basic_fixedsize_stack<boost::context::stack_traits> >' requested here pack_t pt(std::allocator_arg, fs_t(stacksize), ^ In file included from test_stackallocator.cpp:10: /usr/local/include/boost/fiber/future/packaged_task.hpp:61:46: error: no viable conversion from 'const boost::context::basic_fixedsize_stack<boost::context::stack_traits>' to 'typename object_type::allocator_type' (aka 'int') typename object_type::allocator_type a{ alloc }; ^~~~~~~~~~ test_stackallocator.cpp:47:12: note: in instantiation of function template specialization 'boost::fibers::packaged_task<void ()>::packaged_task<boost::_bi::bind_t<void, void (*)(std::__1::basic_string<char>, boost::function<void ()>), boost::_bi::list2<boost::_bi::value<std::__1::basic_string<char> >, boost::_bi::value<boost::function<void ()> > > >, boost::context::basic_fixedsize_stack<boost::context::stack_traits> >' requested here pack_t pt(std::allocator_arg, fs_t(stacksize), ^ 3 errors generated. (END)
該当のソースコード
もとのコードを簡単にしようとしたら何やら無駄な感じの多いコードになってしまいましたが…。
C++
1#include <iostream> 2#include <memory> 3#include <string> 4 5// boost 1.72 6#include <boost/bind.hpp> 7#include <boost/fiber/fiber.hpp> 8#include <boost/fiber/fixedsize_stack.hpp> 9#include <boost/fiber/future/future.hpp> 10#include <boost/fiber/future/packaged_task.hpp> 11#include <boost/function.hpp> 12 13typedef boost::fibers::packaged_task<void()> pack_t; 14typedef boost::fibers::shared_future<void> shared_future_t; 15using fiber = boost::fibers::fiber; 16typedef boost::fibers::fixedsize_stack fs_t; 17typedef boost::function<void()> callable_t; 18 19class Container; 20class Data; 21 22class Container { 23private: 24 Data* mdata; 25public: 26 Container() : mdata(0) {} 27 ~Container(); 28 static void toplevel(const std::string name, callable_t callable); 29 void launch(const std::string name, callable_t callable); 30}; 31 32class Data { 33public: 34 std::string mname; 35 fiber mfib; 36 shared_future_t mfuture; 37 38 Data(const std::string& name, callable_t callable, size_t stacksize); 39 ~Data() {} 40 const std::string Name() { return mname; } 41}; 42 43Data::Data(const std::string& name, callable_t callable, size_t stacksize) : 44 mname(name), mfib(), mfuture() 45{ 46 pack_t pt(std::allocator_arg, fs_t(stacksize), 47 boost::bind(Container::toplevel, name, callable)); 48 mfuture = pt.get_future(); 49 fiber(std::move(pt)).detach(); 50 std::cout << "Data waits." << std::endl; 51} 52 53void callback() 54{ 55 for(int i=0; i<5; ++i) 56 { 57 std::cout << "callback counts: " << i << std::endl; 58 } 59} 60 61Container::~Container() 62{ 63 delete(mdata); 64} 65 66void Container::toplevel(const std::string name, callable_t callable) 67{ 68 std::cout << "toplevel: " << name << std::endl; 69 callable(); 70} 71 72void Container::launch(const std::string name, callable_t callable) 73{ 74 if(mdata) 75 return; 76 std::cout << "launch: " << name << std::endl; 77 mdata = new Data(name, callable, 1024); 78 mdata->mfuture.wait(); 79} 80 81int main() 82{ 83 Container c; 84 c.launch(std::string("from main"), callback); 85}
試したこと
以下のようにスタックアロケータを指定しないコードにしたら通ります。
C++
1pack_t pt(boost::bind(Container::toplevel, name, callable));
/usr/local/include/boost/fiber/future/detail/task_object.hpp の 37行目に
C++
1typedef std::allocator_traits< Allocator > allocator_traits;
とあるのが問題になっているようだというところまではなんとかわかりましたが、その先どうすればよいのかわかりません。
補足
Boost の fiber の issue #106 と似た問題のようなんですが、こちらは3年も前に解決済みとされています。とすると私の書き方になにか間違いがあるのだと思いますが。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/05/07 01:51