我想在我的代码中进行编译时检查,以确保给定的类超载()
运算符,该运算符使用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
。如果签名不正确(例如,在重载运算符时删除
const
),则第一个断言失败。但是,因为编译不会停止,我得到三个错误信息,以及编译器的输出是有点混乱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, const char *, size_t)>::type return_type; ^ rty.cpp:26:75: error: no type named ‘type’ in ‘class std::result_of<unsigned int (Hash::*(Hash, const char*, long unsigned int))(char*, 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'。我注意到,当我注释掉'Hash'的'()'操作符重载时,我收到很多错误消息。在这种情况下有什么办法可以提高编译器的输出吗? – Antonin
我设法找到解决方案。再次感谢Bryan! – Antonin
@Antonin:你可以分享这个解决方案吗? – Eric