![](/img/trans.png)
[英]Passing member functions as arguments to optimizer (passing member functions to a function)
[英]Type of member functions arguments
使用C ++ 11我試圖從函數名中獲取函數參數的類型,授予函數簽名是明確的。 最后,我試圖在調用函數之前檢查參數是否是我想要的類型。
到目前為止,由於此解決方案,我可以使用非成員函數執行此操作: 將函數參數的參數解壓縮到C ++模板類
我稍微編輯了它以獲得以下類:
template<typename T>
struct FunctionSignatureParser; // unimplemented primary template
template<typename Result, typename...Args>
struct FunctionSignatureParser<Result(Args...)>
{
using return_type = Result;
using args_tuple = std::tuple<Args...>;
template <size_t i> struct arg
{
typedef typename std::tuple_element<i, args_tuple>::type type;
};
};
例如,我可以在編譯時檢查函數的類型:
short square(char x) { // 8-bit integer as input, 16-bit integer as output
return short(x)*short(x);
}
int main() {
char answer = 42;
static_assert(std::is_same<char, FunctionSignatureParser<decltype(square)>::arg<0>::type>::value, "Function 'square' does not use an argument of type 'char'");
static_assert(std::is_same<short, FunctionSignatureParser<decltype(square)>::return_type>::value, "Function 'square' does not return a value of type 'short'");
short sqrAnswer = square(answer);
std::cout << "The square of " << +answer << " is " << +sqrAnswer << std::endl;
return 0;
}
但是當我想檢查成員函數的類型時,一些編譯器對它不滿意:
struct Temperature
{
double degrees;
Temperature add(double value);
};
int main() {
Temperature t{16};
double increment{8};
static_assert(std::is_same<double, FunctionSignatureParser<decltype(t.add)>::arg<0>::type>::value, "Method 'Temperature::add' does not use an argument of type 'double'");
std::cout << t.degrees << u8" \u00b0C + " << increment << " == " << t.add(increment).degrees << u8" \u00b0C" << std::endl;
return 0;
}
這是gcc 6.3必須說的:
錯誤:無效使用非靜態成員函數'Temperature Temperature :: add(double)'
這是clang 4.0必須說的:
錯誤:必須調用對非靜態成員函數的引用
我嘗試過這些選項,但無濟於事:
decltype(Temperature::add)
decltype(std::declval<Temperature>().add)
decltype
非靜態成員函數有什么問題? 由於不評估decltype
中的表達式,因此static
限定符無關緊要,對吧?
為了記錄,MSVC12在這種情況下取得了成功。 但我無法判斷Microsoft編譯器是對還是錯。 (請不要讓這個線程成為編譯器之戰)
此外,如果你有一個不涉及初始方法的參數檢查解決方案,我也是開放的。
您需要另一個模板專門化的成員函數,如下所示:
template<typename ClassType, typename Result, typename...Args>
struct FunctionSignatureParser<Result(ClassType::*)(Args...)>
{
using return_type = Result;
using args_tuple = std::tuple<Args...>;
template <size_t i> struct arg
{
typedef typename std::tuple_element<i, args_tuple>::type type;
};
};
它可以像這樣使用:
static_assert(std::is_same<double, FunctionSignatureParser<decltype(&Temperature::add)>::arg<0>::type>::value, "Method 'Temperature::add' does not use an argument of type 'double'");
這適用於gcc 7.2,尚未測試過其他編譯器
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.