我想在我的代碼中進行編譯時檢查,以確保給定的類超載()
運算符,該運算符使用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