На мой дилетантский взгляд GCC всегда поддерживал C++ные шаблоны лучше и строже, чем VC++. Но вот наткнулся на ситуацию, когда GCC 4.9.2/5.1.0 отказывается компилировать код, который успешно проглатывают MSVS2013, MSVS2015, clang 3.4 и 3.6. При этом GCC 5.2.0 уже воспринимает этот код нормально.
Upd. Найден случай, когда все проглатывается.
GCC 4.9.2/5.1.0 не хочет воспринимать вызов шаблонной функции, у которой два параметра шаблона, а при вызове явно задается только один из них:
auto indicator = log_then_abort< signal >( 10u, []( const agent_t & ) { std::cout << "this a signal" << std::endl; } ); |
Вот здесь первый параметр шаблона указан явно -- это тип signal. А второй параметр шаблона компилятор должен был бы вывести самостоятельно. Но не может :(
На всякий случай, вот сама функция log_then_abort:
template< typename M, typename L > log_then_abort_app_indicator_t< M, L > log_then_abort( unsigned int limit, L action ) { return log_then_abort_app_indicator_t< M, L >{ limit, std::move(action) }; } |
Как раз при ее вызове явно указывается M, а вот L требуется вывести компилятору. VC++ и clang с этим успешно справляются. А вот у не самых древних версий GCC с этим проблемы. Хорошо хоть, что у 5.2.0 такой проблемы уже нет. Но это все равно не радует. Придется искать какой-то воркароунд.
PS. Если кого-то интересует, как GCC ругается, то вот его выхлоп полностью:
Compiling ./t1.cpp ...
./t1.cpp: In function 'void test()':
./t1.cpp:98:6: error: no matching function for call to 'log_then_abort(unsigned int, test()::)'
} );
^
./t1.cpp:37:1: note: candidate: template log_then_abort_app_indicator_t log_then_abort(unsigned int, L)
log_then_abort( unsigned int limit, L action )
^
./t1.cpp:37:1: note: template argument deduction/substitution failed:
Такое ощущение, что компилятор хотел еще что-нибудь сказать, но не успел :)
PPS. А вот в таком варианте успешно работает:
struct limits_manager { template< typename M, typename L > static log_then_abort_app_indicator_t< M, L > log_then_abort( unsigned int limit, L lambda ) { return log_then_abort_app_indicator_t< M, L >{ limit, std::move(lambda) }; } }; auto indicator = limits_manager::log_then_abort< signal >( 10u, []( const agent_t & ) { std::cout << "this a signal" << std::endl; } ); |
Комментариев нет:
Отправить комментарий