2016-04-13 8 views
1

boostファンクタを特定のシグネチャで受け入れる関数を作成しようとしています(私たちの目的ではboost::function<int (std::vector<int>&)>としましょう)。前記ファンクタは、例外をスローする悪い習慣を有する悪い図書館から受け取られる。私はそれらを扱う特別な方法があります。これをstderrに投げているとしましょう。だから私は次のコードを作る。不正なインスタンス化についての奇妙な追加ラムダ例外

#include <iostream> 
#include <vector> 
#include <string> 
#include <stdexcept> 

#include <boost/function.hpp> 
#include <boost/lambda/bind.hpp> 
#include <boost/lambda/exceptions.hpp> 

void dispatchError (std::string str) { 
    std::cerr << str << std::endl; 
} 

typedef boost::function<int(std::vector<int>&)> IntFunctor; 

IntFunctor make_safe(std::string method, IntFunctor functor) { 
    // Wrap the method in try-catch 
    return boost::lambda::try_catch(
     // Create a lambda-like out of the method 
     boost::lambda::bind<int>(functor, boost::lambda::_1), 
     // Catch all exceptions thrown 
     boost::lambda::catch_exception<std::exception>(
      boost::lambda::bind(
       &dispatchError, 
       boost::lambda::bind(&std::exception::what, boost::lambda::_e))), 
     // Catch all non-exceptions thrown 
     boost::lambda::catch_all(
      boost::lambda::bind(&dispatchError, "unknown:" + method))); 
} 

int unsafe_vec_manipulator(std::vector<int>& vec) { 
    throw std::runtime_error("Your example is too contrived."); 
} 

int main(int argc, char *argv[]) 
{ 
    std::vector<int> vec(30, 1); 
    IntFunctor f_unsafe, f_safe; 
    f_unsafe = unsafe_vec_manipulator; 
    f_safe = make_safe("manipulator", f_unsafe); 
    return 0; 
} 

私はそれを実行しようとすると、しかし、私が取得:

$ g++ test.cpp -o test && ./test 
In file included from test.cpp:8: 
/usr/local/include/boost/lambda/exceptions.hpp:186:5: error: implicit instantiation of 
     undefined template 'boost::STATIC_ASSERTION_FAILURE<false>' 
    BOOST_STATIC_ASSERT(throws_for_sure<Arg>::value); 
    ^
/usr/local/include/boost/static_assert.hpp:154:13: note: expanded from macro 
     'BOOST_STATIC_ASSERT' 
      sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL... 
      ^
/usr/local/include/boost/lambda/exceptions.hpp:222:19: note: in instantiation of 
     function template specialization 
     'boost::lambda::detail::return_or_throw_phase2<false>::call<int, const 
     boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<2, 
     boost::lambda::function_action<2, boost::lambda::detail::unspecified> >, 
     boost::tuples::tuple<void (*const)(std::__1::basic_string<char>), const 
     boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<2, 
     boost::lambda::function_action<2, boost::lambda::detail::unspecified> >, 
     boost::tuples::tuple<const char *(std::exception::*const)() const, const 
     boost::lambda::lambda_functor<boost::lambda::placeholder<EXCEPTION> >, 
     boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, 
     boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, 
     boost::tuples::null_type, boost::tuples::null_type> > >, 
     boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, 
     boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, 
     boost::tuples::null_type, boost::tuples::null_type> > >, std::__1::vector<int, 
     std::__1::allocator<int> >, const boost::tuples::null_type, const 
     boost::tuples::null_type, std::exception>' requested here 
     >::template call<RET>(arg, CALL_ACTUAL_ARGS); 
       ^
/usr/local/include/boost/lambda/exceptions.hpp:846:18: note: in instantiation of 
     function template specialization 'boost::lambda::detail::return_or_throw<int, 
     boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<2, 
     boost::lambda::function_action<2, boost::lambda::detail::unspecified> >, 
     boost::tuples::tuple<void (*const)(std::__1::basic_string<char>), const 
     boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<2, 
     boost::lambda::function_action<2, boost::lambda::detail::unspecified> >, 

私が原因私がで立ち往生していますブーストのバージョンにブーストフェニックスを使用することはできませんのでご注意ください。私はまた、C++ 98に固執しています。十分な情報であることを願っています。

答えて

1

私が間違っていることを見つけました。キャッチ式のタイプをチェックしていないのを忘れてしまいました。ここには有効なバージョンがあります:

#include <iostream> 
#include <vector> 
#include <string> 
#include <stdexcept> 

#include <boost/function.hpp> 
#include <boost/lambda/bind.hpp> 
#include <boost/lambda/exceptions.hpp> 

int dispatchError (std::string str) { 
    std::cerr << str << std::endl; 
    return -1; 
} 

typedef boost::function<int(std::vector<int>&)> IntFunctor; 

IntFunctor make_safe(std::string method, IntFunctor functor) { 
    // Wrap the method in try-catch 
    return boost::lambda::try_catch(
     // Create a lambda-like out of the method 
     boost::lambda::bind<int>(functor, boost::lambda::_1), 
     // Catch all exceptions thrown 
     boost::lambda::catch_exception<std::exception>(
      boost::lambda::bind(
       &dispatchError, 
       boost::lambda::bind(&std::exception::what, boost::lambda::_e))), 
     // Catch all non-exceptions thrown 
     boost::lambda::catch_all(
      boost::lambda::bind(&dispatchError, "unknown:" + method))); 
} 

int unsafe_vec_manipulator(std::vector<int>& vec) { 
    throw std::runtime_error("Your example is too contrived."); 
} 

int main(int argc, char *argv[]) 
{ 
    std::vector<int> vec(30, 1); 
    IntFunctor f_unsafe, f_safe; 
    f_unsafe = unsafe_vec_manipulator; 
    f_safe = make_safe("manipulator", f_unsafe); 
    f_safe(vec); 
    return 0; 
} 
関連する問題