c 11 – 仿函数的编译时检查
发布时间:2020-12-16 07:14:28 所属栏目:百科 来源:网络整理
导读:我希望在我的代码中进行编译时检查,以确保给定的类重载()运算符,该运算符将const char *和size_t作为参数,并且其返回类型是无符号整数. 我尝试了几个从StackOverflow中获取的代码片段,但我对我编写的解决方案不满意: #include type_traits#include cstdint#
我希望在我的代码中进行编译时检查,以确保给定的类重载()运算符,该运算符将const char *和size_t作为参数,并且其返回类型是无符号整数.
我尝试了几个从StackOverflow中获取的代码片段,但我对我编写的解决方案不满意: #include <type_traits> #include <cstdint> #include <iostream> #include <memory> template<class> struct sfinae_true : std::true_type{}; namespace detail{ template<class T> static auto test(int) -> sfinae_true<decltype(std::declval<T>()(static_cast<const char *>(nullptr),static_cast<size_t>(0u)))>; template<class> static auto test(long) -> std::false_type; } // detail:: template<class T> struct is_functor : decltype(detail::test<T>(0)){ }; template <typename T,typename HashFn,typename std::enable_if<std::is_unsigned<T>::value,int>::type = 0> struct Calculation { Calculation() { static_assert(is_functor<HashFn>(),"BAD signature"); typedef typename std::result_of<decltype(&HashFn::operator())(HashFn,const char *,size_t)>::type return_type; static_assert(std::is_unsigned<return_type>::value,"BAD return type"); } T output() { return static_cast<T>(HashFn()(nullptr,10)); } }; struct Hash { uint32_t operator ()(const char *buffer,size_t n) const { return 65; } }; int main() { Calculation<uint64_t,Hash> c; c.output(); } 对不起代码的长度,我尽量保持尽可能小. 这是我不喜欢我的代码: >如果在重载()运算符时将int替换为参数列表中的size_t,则编译时不会出现错误,因为size_t可以隐式转换为int. rty.cpp: In instantiation of ‘Calculation<T,HashFn,<anonymous> >::Calculation() [with T = long unsigned int; HashFn = Hash; typename std::enable_if<std::is_unsigned<_Tp>::value,int>::type <anonymous> = 0]’: rty.cpp:41:31: required from here rty.cpp:24:5: error: static assertion failed: BAD signature static_assert(is_functor<HashFn>(),"BAD signature"); ^ rty.cpp:25:104: error: no type named ‘type’ in ‘class std::result_of<unsigned int (Hash::*(Hash,const char*,long unsigned int))(char*,long unsigned int) const>’ typedef typename std::result_of<decltype(&HashFn::operator())(HashFn,size_t)>::type return_type; ^ rty.cpp:26:75: error: no type named ‘type’ in ‘class std::result_of<unsigned int (Hash::*(Hash,long unsigned int) const>’ static_assert(std::is_unsigned<return_type>::value,"BAD return type"); >我想对static_assert进行一次调用,例如: static_assert(is_correct_functor<HashFn>(),"BAD implementation"); 我怎样才能做到这一点?谢谢你的帮助. 我正在使用C 11并使用g 4.8进行编译 解决方法
您可以使用此callable_traits获取仿函数的返回类型和参数类型,并使用std :: is_same在static_assert中执行断言
// callable_traits namespace detail { template <class ReturnType,class... Args> struct callable_traits_base { using return_type = ReturnType; using argument_type = std::tuple<Args...>; template<std::size_t I> using arg = typename std::tuple_element<I,argument_type>::type; }; } template <class T> struct callable_traits : callable_traits<decltype(&T::operator())> {}; // lambda / functor template <class ClassType,class ReturnType,class... Args> struct callable_traits<ReturnType(ClassType::*)(Args...) const> : detail::callable_traits_base<ReturnType,Args...> {}; struct Hash { uint32_t operator ()(const char *buffer,size_t n) const { return 65; } }; static_assert(std::is_same<callable_traits<Hash>::return_type,uint32_t>::value,""); static_assert(std::is_same<callable_traits<Hash>::argument_type,std::tuple<const char *,size_t>>::value,""); Online demo 您可以检查callable_traits here的完整实现 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |