hi all
потребовался мне тут чекер компаил-таймный чтобы проверять можно ли некий callable-type вызвать с заданными параметрами.
собственно сам чекер, дело не хитрое, но пепец подкрался откуда не ждал: в тесте он попросту не работал ;( я некоторое (заметное) время я еще пробовал его реанимировать и так и эдак печатая разнообразный debug spam про типы тут участвующие -- все казалось бы хорошо, но финальный чекер не работает хоть тресни ;(
затрахавшись с ним в конец (и уже собираясь сдаваться) я попробовал собрать тестик clang'ом 3.2 -- и он зараза работает как и ожидалось!
я уже было сильно расстроился и собрался писать багу в GCCшную багзилу, сделал минимальный пример (см ниже), но все таки решил слегка его изменить (см вариант #1 и #2 в примере) -- оказалось что мой изначальный вариант (без add_pointer) ни в какую не хочет работать (что очевидно бага), но второй работает замечательно (что меня все таки радует)...
// kate: hl C++11;
#include <iostream>
#include <type_traits>
#include <utility>
struct is_callable_with_checker
{
typedef char yes_type;
typedef char (&no_type)[2];
template <typename...>
static no_type test(...);
#if 1
// case #1 (original): simple add '*' to a deduced type to form a pointer type parameter
template <typename Callable, typename... Args>
static yes_type test(
/*const*/ decltype(
std::declval<Callable>()(std::forward<Args>(std::declval<Args>())...)
, void()
)* /*const*/
);
#else
// case #2: form a pointer type via metafunction
template <typename Callable, typename... Args>
static yes_type test(
typename std::add_pointer<
decltype(
std::declval<Callable>()(std::forward<Args>(std::declval<Args>())...)
, void()
)
>::type
);
#endif
};
template <typename Callable, typename... Args>
struct is_callable_with
: std::is_same<
decltype(is_callable_with_checker::template test<Callable, Args...>(nullptr))
, is_callable_with_checker::yes_type
>
{};
// Some functor w/ overloaded operator(...)
struct test
{
int operator()(int) const
{
return 123;
}
double operator()(int, double) const
{
return 123.123;
}
};
int main()
{
// expect 1
std::cout << is_callable_with<test, int>::type::value << std::endl;
// expect 1
std::cout << is_callable_with<test, int, double>::type::value << std::endl;
// expect 0
std::cout << is_callable_with<test, int, std::ostream&>::type::value << std::endl;
return 0;
}
собственно вопросы к просвещенной общественности:
0) кто видит разницу в получаемом типе параметра функции `yes_type test(...)`?
1) если ее нету, очевидно это бага -- может кто знает с чем (с какой другой багой) она связана? может уже зарепортили что-то похожее?
PS: кастую Masterkent'а